📄 screen.c
字号:
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 + -