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

📄 screen.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (VIsual_mode == 'V')	/* linewise */
		    fromcol = 0;
		else
		    getvcol(wp, top, (colnr_t *)&fromcol, NULL, NULL);
	    }
	    if (VIsual_mode != 'V' && lnum == bot->lnum)
	    {
		if (*p_sel == 'e' && bot->col == 0)
		{
		    fromcol = -10;
		    tocol = MAXCOL;
		}
		else
		{
		    FPOS pos;

		    pos = *bot;
		    if (*p_sel == 'e')
			--pos.col;
		    getvcol(wp, &pos, NULL, NULL, (colnr_t *)&tocol);
		    ++tocol;
		}
	    }

	}
#ifndef MSDOS
	/* Check if the character under the cursor should not be inverted */
	if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
# ifdef USE_GUI
		&& !gui.in_use
# endif
		)
	    noinvcur = TRUE;
#endif

	/*
	 * 'nowrap': adjust for when the inverted text is left of the screen,
	 * and when the start of the inverted text is left of the screen.
	 */
	if (!wp->w_p_wrap)
	{
	    if (tocol <= (int)wp->w_leftcol)
		fromcol = 0;
	    else if (fromcol >= 0 && fromcol < (int)wp->w_leftcol)
		fromcol = wp->w_leftcol;
	}

	/* if inverting in this line, can't optimize cursor positioning */
	if (fromcol >= 0)
	    area_highlighting = TRUE;
    }

    /*
     * handle incremental search position highlighting
     */
    else if (highlight_match && wp == curwin && search_match_len)
    {
	if (lnum == curwin->w_cursor.lnum)
	{
	    getvcol(curwin, &(curwin->w_cursor),
					    (colnr_t *)&fromcol, NULL, NULL);
	    curwin->w_cursor.col += search_match_len;
	    getvcol(curwin, &(curwin->w_cursor),
					    (colnr_t *)&tocol, NULL, NULL);
	    curwin->w_cursor.col -= search_match_len;
	    area_highlighting = TRUE;
	    attr = hl_attr(HLF_I);
	    if (fromcol == tocol)	/* do at least one character */
		tocol = fromcol + 1;	/* happens when past end of line */
	}
    }

    ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
#ifdef EXTRA_SEARCH
    matchp = ptr;
#endif
#ifdef SYNTAX_HL
    line = ptr;
    rcol = 0;
#endif
#ifdef MULTI_BYTE
    line_head = ptr;
#endif

    /* find start of trailing whitespace */
    if (wp->w_p_list && lcs_trail)
    {
	trail = ptr + STRLEN(ptr);
	while (trail > ptr && vim_iswhite(trail[-1]))
	    --trail;
	extra_check = TRUE;
    }

    /*
     * 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the
     * first character to be displayed.
     */
    if (!wp->w_p_wrap || wp->w_skipcol)
    {
	if (wp->w_p_wrap)
	    v = wp->w_skipcol;
	else
	    v = wp->w_leftcol;
	while (vcol < v && *ptr)
	{
	    c = win_chartabsize(wp, *ptr++, (colnr_t)vcol);
	    vcol += c;
#ifdef SYNTAX_HL
	    ++rcol;
#endif
	}
	/* handle a character that's not completely on the screen */
	if (vcol > v)
	{
	    vcol -= c;
	    --ptr;
#ifdef SYNTAX_HL
	    --rcol;
#endif
	    n_skip = v - vcol;
	}
    }

#ifdef EXTRA_SEARCH
    /*
     * Handle highlighting the last used search pattern.
     */
    if (search_hl_prog != NULL)
    {
	reg_ic = search_hl_ic;
	for (;;)
	{
	    if (vim_regexec(search_hl_prog, matchp, TRUE))
	    {
		search_hl_start = search_hl_prog->startp[0];
		search_hl_end = search_hl_prog->endp[0];
		if (search_hl_end <= ptr)    /* match before leftcol */
		{
		    if (matchp == search_hl_end) /* empty match */
			++matchp;
		    else
			matchp = search_hl_end;
		    continue;
		}
		if (search_hl_start < ptr)  /* match at leftcol */
		    search_attr = search_hl_attr;
	    }
	    else
	    {
		search_hl_start = NULL;
		search_hl_end = NULL;
	    }
	    break;
	}
	if (search_hl_start != NULL)
	    area_highlighting = TRUE;
    }
#endif

    screenp = current_LinePointer;
#ifdef RIGHTLEFT
    if (wp->w_p_rl)
    {
	col = Columns - 1;		    /* col follows screenp here */
	screenp += Columns - 1;
    }
#endif

    /* add a line number if 'number' is set */
    if (wp->w_p_nu)
    {
	sprintf((char *)extra, "%7ld ", (long)lnum);
#ifdef RIGHTLEFT
	if (wp->w_p_rl)			    /* reverse line numbers */
	{
	    char_u *c1, *c2, t;

	    for (c1 = extra, c2 = extra + STRLEN(extra) - 1; c1 < c2;
								   c1++, c2--)
	    {
		t = *c1;
		*c1 = *c2;
		*c2 = t;
	    }
	}
#endif
	n_number = 8;
	n_extra = 8;
	p_extra = extra;
	c_extra = NUL;
	vcol -= 8;	/* so vcol is right when line number has been printed */
	n_attr = 8;
	extra_attr = hl_attr(HLF_N);
	saved_attr2 = 0;
    }

    /*
     * Repeat for the whole displayed line.
     */
    for (;;)
    {
	/* handle Visual or match highlighting in this line (but not when
	 * still in the line number) */
	if (area_highlighting && n_number <= 0)
	{
	    if (((vcol == fromcol
			    && !(noinvcur
				&& (colnr_t)vcol == wp->w_virtcol))
			|| (noinvcur
			    && (colnr_t)vcol == wp->w_virtcol + 1
			    && vcol >= fromcol))
		    && vcol < tocol)
		area_attr = attr;		    /* start highlighting */
	    else if (area_attr
		    && (vcol == tocol
			|| (noinvcur
			    && (colnr_t)vcol == wp->w_virtcol)))
		area_attr = 0;			    /* stop highlighting */

#ifdef EXTRA_SEARCH
	    /*
	     * Check for start/end of search pattern match.
	     * After end, check for start/end of next match.
	     * When another match, have to check for start again.
	     * Watch out for matching an empty string!
	     */
	    if (!n_extra)
	    {
		for (;;)
		{
		    if (ptr == search_hl_start)
			search_attr = search_hl_attr;
		    if (ptr == search_hl_end)
		    {
			search_attr = 0;
			reg_ic = search_hl_ic;
			if (vim_regexec(search_hl_prog, ptr, FALSE))
			{
			    search_hl_start = search_hl_prog->startp[0];
			    search_hl_end = search_hl_prog->endp[0];
			    if (search_hl_start != search_hl_end)
				continue;
			    ++search_hl_end; /* try again after empty match */
			}
		    }
		    break;
		}
	    }
#endif

	    if (area_attr)
		char_attr = area_attr;
#ifdef SYNTAX_HL
	    else if (!search_attr && has_syntax)
		char_attr = syntax_attr;
#endif
	    else
		char_attr = search_attr;
	}

    /*
     * Get the next character to put on the screen.
     */

	/*
	 * If 'showbreak' is set it contains the characters to put at the
	 * start of each broken line.
	 */
	if (*p_sbr != 0)
	{
	    if (
#ifdef RIGHTLEFT
		    (wp->w_p_rl ? col == -1 : col == Columns)
#else
		    col == Columns
#endif
		    && (*ptr != NUL
			|| (wp->w_p_list && lcs_eol != NUL)
			|| (n_extra && (c_extra != NUL || *p_extra != NUL)))
		    && vcol != 0)
	    {
		showbreak = p_sbr;
		saved_attr1 = char_attr;	/* save current attributes */
	    }
	    if (showbreak != NULL)
	    {
		if (*showbreak == NUL)
		{
		    showbreak = NULL;
		    char_attr = saved_attr1;	/* restore attributes */
		}
		else
		{
		    c = *showbreak++;
		    char_attr = hl_attr(HLF_AT);
		}
	    }
	}

	if (showbreak == NULL)
	{
	    /*
	     * The 'extra' array contains the extra stuff that is inserted to
	     * represent special characters (non-printable stuff).  When all
	     * characters are the same, c_extra is used.
	     * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
	     */
	    if (n_extra)
	    {
		if (c_extra)
		    c = c_extra;
		else
		    c = *p_extra++;
		--n_extra;
	    }
	    else
	    {
		c = *ptr++;
#ifdef MULTI_BYTE
		bCharacter = 1;
#endif
		if (extra_check)
		{
#ifdef SYNTAX_HL
		    if (has_syntax)
		    {
			syntax_attr = get_syntax_attr(rcol++, line);
			if (!area_attr && !search_attr)
			    char_attr = syntax_attr;
		    }
#endif
		    /*
		     * Found last space before word: check for line break
		     */
		    if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)
							  && !wp->w_p_list)
		    {
			n_extra = win_lbr_chartabsize(wp, ptr - 1,
				(colnr_t)vcol, NULL) - 1;
			c_extra = ' ';
			if (vim_iswhite(c))
			    c = ' ';
		    }

		    if (trail != NULL && ptr > trail && c == ' ')
		    {
			c = lcs_trail;
			if (!area_attr && !search_attr)
			{
			    n_attr = 1;
			    extra_attr = hl_attr(HLF_AT);
			    saved_attr2 = char_attr; /* save current attr */
			}
		    }
		}

		/*
		 * Handling of non-printable characters.
		 */
		if (!safe_vim_isprintc(c))
		{
		    /*
		     * when getting a character from the file, we may have to
		     * turn it into something else on the way to putting it
		     * into 'NextScreen'.
		     */
		    if (c == TAB && (!wp->w_p_list || lcs_tab1))
		    {
			/* tab amount depends on current column */
			n_extra = (int)wp->w_buffer->b_p_ts -
					 vcol % (int)wp->w_buffer->b_p_ts - 1;
			if (wp->w_p_list)
			{
			    c = lcs_tab1;
			    c_extra = lcs_tab2;
			    if (!area_attr && !search_attr)
			    {
				n_attr = n_extra + 1;
				extra_attr = hl_attr(HLF_AT);
				saved_attr2 = char_attr; /* save current attr */
			    }
			}
			else
			{
			    c_extra = ' ';
			    c = ' ';
			}
		    }
		    else if (c == NUL && wp->w_p_list && lcs_eol != NUL)
		    {
			p_extra = (char_u *)"";
			n_extra = 1;
			c_extra = NUL;
			c = lcs_eol;
			--ptr;	    /* put it back at the NUL */
			char_attr = hl_attr(HLF_AT);
		    }
		    else if (c != NUL)
		    {
			p_extra = transchar(c);
			n_extra = charsize(c) - 1;
			c_extra = NUL;
			c = *p_extra++;
		    }
		}
	    }
	    if (n_attr)
		char_attr = extra_attr;
	}

	/*
	 * At end of the text line.
	 */
	if (c == NUL)
	{
	    if (area_attr)
	    {
		/* invert at least one char, used for Visual and empty line or
		 * highlight match at end of line. If it's beyond the last
		 * char on the screen, just overwrite that one (tricky!) */
		if (vcol == fromcol)
		{
#ifdef RIGHTLEFT
		    if (wp->w_p_rl)
		    {
			if (col < 0)
			{
			    ++screenp;
			    ++col;
			}
		    }
		    else
#endif
		    {
			if (col >= Columns)
			{
			    --screenp;
			    --col;
			}
		    }
		    *screenp = ' ';
		    *(screenp + Columns) = char_attr;
#ifdef RIGHTLEFT
		    if (wp->w_p_rl)
			--col;
		    else
#endif
			++col;
		}
	    }

	    SCREEN_LINE(screen_row, col, TRUE, wp->w_p_rl);
	    row++;

	    /*
	     * Update w_cline_height if we can (saves a call to plines()
	     * later).
	     */
	    if (wp == curwin && lnum == curwin->w_cursor.lnum)
	    {
		curwin->w_cline_row = startrow;
		curwin->w_cline_height = row - startrow;
		curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
	    }

	    break;
	}

	/*
	 * At end of screen line.
	 */
	if (
#ifdef RIGHTLEFT
	    wp->w_p_rl ? (col < 0) :
#endif
				    (col >= Columns))
	{
	    SCREEN_LINE(screen_row, col, TRUE, wp->w_p_rl);
	    col = 0;
	    ++row;
	    ++screen_row;
	    if (!wp->w_p_wrap)
		break;
	    if (row == endrow)	    /* line got too long for screen */
	    {
		++row;
		break;
	    }

	    /*
	     * Special trick to make copy/paste of wrapped lines work with
	     * xterm/screen: write an extra character beyond the end of the
	     * line. This will work with all terminal types (regardless of the
	     * xn,am settings).
	     * Only do this on a fast tty.
	     * Only do this if the cursor is on the current line (something
	     * has been written in it).
	     * Don't do this for the GUI.
	     */
	    if (p_tf && screen_cur_row == screen_row - 1
#ifdef USE_GUI
		     && !gui.in_use
#endif
					)
	    {
		if (screen_cur_col != Columns)
		    screen_char(LinePointers[screen_row - 1] + Columns - 1,
					  screen_row - 1, (int)(Columns - 1));
		screen_char(LinePointers[screen_row],
						screen_row - 1, (int)Columns);
		screen_start();		/* don't know where cursor is now */
	    }

	    screenp = current_LinePointer;
#ifdef RIGHTLEFT
	    if (wp->w_p_rl)
	    {
		col = Columns - 1;	/* col is not used if breaking! */
		screenp += Columns - 1;
	    }
#endif
	}

	/* line continues beyond line end */
	if (lcs_ext
		&& !wp->w_p_wrap
		&& (
#ifdef RIGHTLEFT
		    wp->w_p_rl ? col == 0 :
#endif

⌨️ 快捷键说明

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