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

📄 charset.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
 *
 * No check for (c < 0x100) to make it a bit faster.
 * This is the most often used function, keep it fast!
 */
    int
safe_vim_isprintc(c)
    int c;
{
    return (chartab[c] & CHAR_IP);
}

/*
 * like chartabsize(), but also check for line breaks on the screen
 */
    int
lbr_chartabsize(s, col)
    unsigned char   *s;
    colnr_t	    col;
{
    if (!curwin->w_p_lbr && *p_sbr == NUL)
    {
	RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, *s, col)
    }

    return win_lbr_chartabsize(curwin, s, col, NULL);
}

/*
 * This function is used very often, keep it fast!!!!
 * Warning: *head is only set if it's a non-zero value, init to 0 before
 * calling.
 */
    int
win_lbr_chartabsize(wp, s, col, head)
    WIN		    *wp;
    unsigned char   *s;
    colnr_t	    col;
    int		    *head;
{
    int	    c = *s;
    int	    size;
    colnr_t col2;
    colnr_t colmax;
    int	    added;
    int     numberextra;

/*
 * No 'linebreak' and 'showbreak': return quickly.
 */
    if (!wp->w_p_lbr && *p_sbr == NUL)
    {
	RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, c, col)
    }

/*
 * First get normal size, without 'linebreak'
 */
    size = win_chartabsize(wp, c, col);
/*
 * If 'linebreak' set check at a blank before a non-blank if the line needs a
 * break here
 */
    if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(s[1]) &&
					       !wp->w_p_list && wp->w_p_wrap)
    {
	numberextra = wp->w_p_nu? 8: 0;
	/* count all characters from first non-blank after a blank up to next
	 * non-blank after a blank */
	col2 = col;
	colmax = (((col + numberextra) / Columns) + 1) * Columns;
	while ((c = *++s) != NUL && (vim_isbreak(c)
		|| (!vim_isbreak(c) && (col2 == col || !vim_isbreak(s[-1])))))
	{
	    col2 += win_chartabsize(wp, c, col2);
	    if (col2 + numberextra >= colmax)		/* doesn't fit */
	    {
		size = Columns - ((col + numberextra) % Columns);
		break;
	    }
	}
    }

/*
 * May have to add something for 'showbreak' string at start of line
 * Set *head to the size of what we add.
 */
    added = 0;
    if (*p_sbr != NUL && wp->w_p_wrap && col)
    {
	numberextra = wp->w_p_nu? 8: 0;
	col = (col + numberextra) % Columns;
	if (col == 0 || col + size > (colnr_t)Columns)
	{
	    added = STRLEN(p_sbr);
	    size += added;
	    if (col != 0)
		added = 0;
	}
    }
    if (head != NULL)
	*head = added;
    return size;
}

/*
 * Get virtual column number of pos.
 *  start: on the first position of this character (TAB, ctrl)
 * cursor: where the cursor is on this character (first char, except for TAB)
 *    end: on the last position of this character (TAB, ctrl)
 *
 * This is used very often, keep it fast!
 */
    void
getvcol(wp, pos, start, cursor, end)
    WIN		*wp;
    FPOS	*pos;
    colnr_t	*start;
    colnr_t	*cursor;
    colnr_t	*end;
{
    int		    col;
    colnr_t	    vcol;
    char_u	   *ptr;
    int		    incr;
    int		    head;
    int		    ts = wp->w_buffer->b_p_ts;
    int		    c;

    vcol = 0;
    ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);

    /*
     * This function is used very often, do some speed optimizations.
     * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
     */
    if ((!wp->w_p_list || lcs_tab1) && !wp->w_p_lbr && *p_sbr == NUL)
    {
	head = 0;
	for (col = pos->col; ; --col, ++ptr)
	{
	    c = *ptr;
	    /* make sure we don't go past the end of the line */
	    if (c == NUL)
	    {
		incr = 1;	/* NUL at end of line only takes one column */
		break;
	    }
	    /* A tab gets expanded, depending on the current column */
	    if (c == TAB)
		incr = ts - (vcol % ts);
	    else
		incr = CHARSIZE(c);

	    if (col == 0)	/* character at pos.col */
		break;

	    vcol += incr;
	}
    }
    else
    {
	for (col = pos->col; ; --col, ++ptr)
	{
	    /* A tab gets expanded, depending on the current column */
	    head = 0;
	    incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
	    /* make sure we don't go past the end of the line */
	    if (*ptr == NUL)
	    {
		incr = 1;	/* NUL at end of line only takes one column */
		break;
	    }

	    if (col == 0)	/* character at pos.col */
		break;

	    vcol += incr;
	}
    }
    if (start != NULL)
	*start = vcol + head;
    if (end != NULL)
	*end = vcol + incr - 1;
    if (cursor != NULL)
    {
	if (*ptr == TAB && (State & NORMAL) && !wp->w_p_list
					 && !(VIsual_active && *p_sel == 'e'))
	    *cursor = vcol + incr - 1;	    /* cursor at end */
	else
	    *cursor = vcol + head;	    /* cursor at start */
    }
}

/*
 * Get the most left and most right virtual column of pos1 and pos2.
 * Used for Visual block mode.
 */
    void
getvcols(pos1, pos2, left, right)
    FPOS    *pos1, *pos2;
    colnr_t *left, *right;
{
    colnr_t	l1, l2, r1, r2;

    getvcol(curwin, pos1, &l1, NULL, &r1);
    getvcol(curwin, pos2, &l2, NULL, &r2);
    if (l1 < l2)
	*left = l1;
    else
	*left = l2;
    if (r1 > r2)
	*right = r1;
    else
	*right = r2;
}

/*
 * skipwhite: skip over ' ' and '\t'.
 */
    char_u *
skipwhite(p)
    char_u	*p;
{
    while (vim_iswhite(*p)) /* skip to next non-white */
	++p;
    return p;
}

/*
 * skipdigits: skip over digits;
 */
    char_u *
skipdigits(p)
    char_u	*p;
{
    while (isdigit(*p))	/* skip to next non-digit */
	++p;
    return p;
}

/*
 * vim_isdigit: version of isdigit() that can handle characters > 0x100.
 */
    int
vim_isdigit(c)
    int	    c;
{
    return (c > 0 && c < 0x100 && isdigit(c));
}

/*
 * skiptowhite: skip over text until ' ' or '\t' or NUL.
 */
    char_u *
skiptowhite(p)
    char_u	*p;
{
    while (*p != ' ' && *p != '\t' && *p != NUL)
	++p;
    return p;
}

/*
 * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
 */
    char_u *
skiptowhite_esc(p)
    char_u	*p;
{
    while (*p != ' ' && *p != '\t' && *p != NUL)
    {
	if ((*p == '\\' || *p == Ctrl('V')) && *(p + 1) != NUL)
	    ++p;
	++p;
    }
    return p;
}

/*
 * Getdigits: Get a number from a string and skip over it.
 *
 * Note: the argument is a pointer to a char_u pointer!
 */

    long
getdigits(pp)
    char_u **pp;
{
    char_u	*p;
    long	retval;

    p = *pp;
    retval = atol((char *)p);
    p = skipdigits(p);	    /* skip to next non-digit */
    *pp = p;
    return retval;
}

/*
 * Return TRUE if "lbuf" is empty or only contains blanks.
 */
    int
vim_isblankline(lbuf)
    char_u	*lbuf;
{
    char_u	*p;

    p = skipwhite(lbuf);
    return (*p == NUL || *p == '\r' || *p == '\n');
}

/*
 * Convert a string into a long and/or unsigned long, taking care of
 * hexadecimal and octal numbers.
 * If "hexp" is not NULL, returns a flag to indicate the type of the number:
 *  0	    decimal
 *  '0'	    octal
 *  'X'	    hex
 *  'x'	    hex
 * If "len" is not NULL, the length of the number in characters is returned.
 * If "nptr" is not NULL, the signed result is returned in it.
 * If "unptr" is not NULL, the unsigned result is returned in it.
 */
    void
vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
    char_u		*start;
    int			*hexp;	    /* return: type of number 0 = decimal, 'x'
				       or 'X' is hex, '0' = octal */
    int			*len;	    /* return: detected length of number */
    int			dooct;	    /* recognize octal number */
    int			dohex;	    /* recognize hex number */
    long		*nptr;	    /* return: signed result */
    unsigned long	*unptr;	    /* return: unsigned result */
{
    char_u	    *ptr = start;
    int		    hex = 0;		/* default is decimal */
    int		    negative = FALSE;
    long	    n = 0;
    unsigned long   un = 0;

    if (ptr[0] == '-')
    {
	negative = TRUE;
	++ptr;
    }

    if (ptr[0] == '0')			/* could be hex or octal */
    {
	hex = ptr[1];
	if (dohex && (hex == 'X' || hex == 'x') && isxdigit(ptr[2]))
	    ptr += 2;			/* hexadecimal */
	else
	{
	    if (dooct && isdigit(hex))
		hex = '0';		/* octal */
	    else
		hex = 0;		/* 0 by itself is decimal */
	}
    }

    /*
     * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
     */
    if (hex)
    {
	if (hex == '0')
	{
	    /* octal */
	    while ('0' <= *ptr && *ptr <= '7')
	    {
		n = 8 * n + (long)(*ptr - '0');
		un = 8 * un + (unsigned long)(*ptr - '0');
		++ptr;
	    }
	}
	else
	{
	    /* hex */
	    while (isxdigit(*ptr))
	    {
		n = 16 * n + (long)hex2nr(*ptr);
		un = 16 * un + (unsigned long)hex2nr(*ptr);
		++ptr;
	    }
	}
    }
    else
    {
	/* decimal */
	while (isdigit(*ptr))
	{
	    n = 10 * n + (long)(*ptr - '0');
	    un = 10 * un + (unsigned long)(*ptr - '0');
	    ++ptr;
	}
    }

    if (!hex && negative)   /* account for leading '-' for decimal numbers */
	n = -n;

    if (hexp != NULL)
	*hexp = hex;
    if (len != NULL)
	*len = ptr - start;
    if (nptr != NULL)
	*nptr = n;
    if (unptr != NULL)
	*unptr = un;
}

/*
 * Return the value of a single hex character.
 * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
 */
    int
hex2nr(c)
    int	    c;
{
    if (c >= 'a')
	return c - 'a' + 10;
    if (c >= 'A')
	return c - 'A' + 10;
    return c - '0';
}

⌨️ 快捷键说明

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