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

📄 misc1.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
	    {
		STRNCPY(leader, saved_line, lead_len);
		leader[lead_len] = NUL;

		/*
		 * Replace leader with lead_repl, right or left adjusted
		 */
		if (lead_repl != NULL)
		{
		    for (p = lead_flags; *p && *p != ':'; ++p)
			if (*p == COM_RIGHT || *p == COM_LEFT)
			    break;
		    if (*p == COM_RIGHT)    /* right adjusted leader */
		    {
			/* find last non-white in the leader to line up with */
			for (p = leader + lead_len - 1; p > leader &&
							 vim_iswhite(*p); --p)
			    ;

			++p;
			if (p < leader + lead_repl_len)
			    p = leader;
			else
			    p -= lead_repl_len;
			mch_memmove(p, lead_repl, (size_t)lead_repl_len);
			if (p + lead_repl_len > leader + lead_len)
			    p[lead_repl_len] = NUL;

			/* blank-out any other chars from the old leader. */
			while (--p >= leader)
			    if (!vim_iswhite(*p))
				*p = ' ';
		    }
		    else		    /* left adjusted leader */
		    {
			p = skipwhite(leader);
			mch_memmove(p, lead_repl, (size_t)lead_repl_len);

			/* blank-out any other chars from the old leader. */
			for (p += lead_repl_len; p < leader + lead_len; ++p)
			    if (!vim_iswhite(*p))
				*p = ' ';
			*p = NUL;
		    }

		    /* Recompute the indent, it may have changed. */
		    if (curbuf->b_p_ai
#ifdef SMARTINDENT
					|| curbuf->b_p_si
#endif
							   )
			newindent = get_indent_str(leader);
		}

		lead_len = STRLEN(leader);
		if (extra_space)
		{
		    leader[lead_len++] = ' ';
		    leader[lead_len] = NUL;
		}

		newcol = lead_len;

		/*
		 * if a new indent will be set below, remove the indent that
		 * is in the comment leader
		 */
		if (newindent
#ifdef SMARTINDENT
				|| did_si
#endif
					   )
		{
		    while (lead_len && vim_iswhite(*leader))
		    {
			--lead_len;
			--newcol;
			++leader;
		    }
		}

	    }
#ifdef SMARTINDENT
	    did_si = can_si = FALSE;
#endif
	}
	else if (comment_end != NULL)
	{
	    /*
	     * We have finished a comment, so we don't use the leader.
	     * If this was a C-comment and 'ai' or 'si' is set do a normal
	     * indent to align with the line containing the start of the
	     * comment.
	     */
	    if (comment_end[0] == '*' && comment_end[1] == '/' &&
			(curbuf->b_p_ai
#ifdef SMARTINDENT
					|| curbuf->b_p_si
#endif
							   ))
	    {
		old_cursor = curwin->w_cursor;
		curwin->w_cursor.col = comment_end - saved_line;
		if ((pos = findmatch(NULL, NUL)) != NULL)
		{
		    curwin->w_cursor.lnum = pos->lnum;
		    newindent = get_indent();
		}
		curwin->w_cursor = old_cursor;
	    }
	}
    }

    /* (State == INSERT || State == REPLACE), only when dir == FORWARD */
    if (p_extra != NULL)
    {
	*p_extra = saved_char;		/* restore char that NUL replaced */

	/*
	 * When 'ai' set or "del_spaces" TRUE, skip to the first non-blank.
	 *
	 * When in REPLACE mode, put the deleted blanks on the replace stack,
	 * preceded by a NUL, so they can be put back when a BS is entered.
	 */
	if (State == REPLACE)
	    replace_push(NUL);	    /* end of extra blanks */
	if (curbuf->b_p_ai || del_spaces)
	{
	    while (*p_extra == ' ' || *p_extra == '\t')
	    {
		if (State == REPLACE)
		    replace_push(*p_extra);
		++p_extra;
	    }
	}
	if (*p_extra != NUL)
	    did_ai = FALSE;	    /* append some text, don't trucate now */
    }

    if (p_extra == NULL)
	p_extra = (char_u *)"";		    /* append empty line */

    /* concatenate leader and p_extra, if there is a leader */
    if (lead_len)
    {
	STRCAT(leader, p_extra);
	p_extra = leader;
    }

    old_cursor = curwin->w_cursor;
    if (dir == BACKWARD)
	--curwin->w_cursor.lnum;
    if (ml_append(curwin->w_cursor.lnum, p_extra, (colnr_t)0, FALSE) == FAIL)
	goto theend;
    changed_line_abv_curs();	    /* update cursor screen position later */
    mark_adjust(curwin->w_cursor.lnum + 1, (linenr_t)MAXLNUM, 1L, 0L);
    if (newindent
#ifdef SMARTINDENT
		    || did_si
#endif
				)
    {
	++curwin->w_cursor.lnum;
#ifdef SMARTINDENT
	if (did_si)
	{
	    if (p_sr)
		newindent -= newindent % (int)curbuf->b_p_sw;
	    newindent += (int)curbuf->b_p_sw;
	}
#endif
	set_indent(newindent, FALSE);
	/*
	 * In REPLACE mode, for each character in the new indent, there must
	 * be a NUL on the replace stack, for when it is deleted with BS
	 */
	if (State == REPLACE)
	    for (n = 0; n < (int)curwin->w_cursor.col; ++n)
		replace_push(NUL);
	newcol += curwin->w_cursor.col;
#ifdef SMARTINDENT
	if (no_si)
	    did_si = FALSE;
#endif
    }
    /*
     * In REPLACE mode, for each character in the extra leader, there must be
     * a NUL on the replace stack, for when it is deleted with BS.
     */
    if (State == REPLACE)
	while (lead_len-- > 0)
	    replace_push(NUL);

    curwin->w_cursor = old_cursor;

    if (dir == FORWARD)
    {
	if (redraw)	/* want to know the old number of screen lines */
	{
	    old_plines = plines(curwin->w_cursor.lnum);
	    new_plines = old_plines;
	}
	if (trunc_line || State == INSERT || State == REPLACE)
	{
	    if (trunc_line)
	    {
		/* find start of trailing white space */
		for (n = STRLEN(saved_line); n > 0 &&
					  vim_iswhite(saved_line[n - 1]); --n)
		    ;
		saved_line[n] = NUL;
	    }
	    else		    /* truncate current line at cursor */
		*(saved_line + curwin->w_cursor.col) = NUL;
	    ml_replace(curwin->w_cursor.lnum, saved_line, FALSE);
	    saved_line = NULL;
#ifdef SYNTAX_HL
	    /* recompute syntax hl. for this line */
	    syn_changed(curwin->w_cursor.lnum);
#endif
	    if (redraw)
		new_plines = plines(curwin->w_cursor.lnum);
	}

	/*
	 * Get the cursor to the start of the line, so that 'curwin->w_wrow'
	 * gets set to the right physical line number for the stuff that
	 * follows...
	 */
	curwin->w_cursor.col = 0;

	if (redraw)
	{
	    /*
	     * If we're doing an open on the last logical line, then go ahead
	     * and scroll the screen up. Otherwise, just insert blank lines
	     * at the right place if the number of screen lines changed.
	     * We use calls to plines() in case the cursor is resting on a
	     * long line, we want to know the row below the line.
	     *
	     * Note: using w_cline_row from before the change!
	     */
	    n = curwin->w_cline_row + new_plines;
	    if (n + plines(curwin->w_cursor.lnum + 1) - 1 >=
						      curwin->w_height - p_so)
	    {
		/* If redraw < 0, will later redraw with NOT_VALID, thus not
		 * scroll but redraw.  Scroll the text here instead. */
		if (redraw < 0)
		    win_del_lines(curwin, 0, plines(curwin->w_topline),
								  TRUE, TRUE);
		scrollup(1L);
	    }
	    else
		win_ins_lines(curwin, n,
		  plines(curwin->w_cursor.lnum + 1) + new_plines - old_plines,
								  TRUE, TRUE);
	}

	/*
	 * Put the cursor on the new line.  Careful: the scrollup() above may
	 * have moved w_cursor, we must use old_cursor.
	 */
	curwin->w_cursor.lnum = old_cursor.lnum + 1;
    }
    else if (redraw)
    {
	/*
	 * Insert physical line above current line.
	 * Note: use w_cline_row from before the change.
	 */
	win_ins_lines(curwin, curwin->w_cline_row, 1, TRUE, TRUE);
    }

    curwin->w_cursor.col = newcol;

#ifdef LISPINDENT
    /*
     * May do lisp indenting.
     */
    if (leader == NULL && curbuf->b_p_lisp && curbuf->b_p_ai)
	fixthisline(get_lisp_indent);
#endif
#ifdef CINDENT
    /*
     * May do indenting after opening a new line.
     */
    if (leader == NULL && curbuf->b_p_cin &&
	    in_cinkeys(dir == FORWARD ? KEY_OPEN_FORW :
			KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
	fixthisline(get_c_indent);
#endif

    /*
     * w_botline won't change much when inserting a new line.
     */
    approximate_botline();

    if (redraw > 0)
    {
	update_topline();
	update_screen(VALID_BEF_CURSCHAR);
    }
    changed();

    retval = TRUE;		/* success! */
theend:
    vim_free(saved_line);
    vim_free(allocated);
    return retval;
}

/*
 * get_leader_len() returns the length of the prefix of the given string
 * which introduces a comment.	If this string is not a comment then 0 is
 * returned.
 * When "flags" is non-zero, it is set to point to the flags of the recognized
 * comment leader.
 */
    int
get_leader_len(line, flags)
    char_u  *line;
    char_u  **flags;
{
    int	    i, j;
    int	    got_com = FALSE;
    int	    found_one;
    char_u  part_buf[COM_MAX_LEN];  /* buffer for one option part */
    char_u  *string;		    /* pointer to comment string */
    char_u  *list;

    if (!fo_do_comments)	    /* don't format comments at all */
	return 0;

    i = 0;
    while (vim_iswhite(line[i]))    /* leading white space is ignored */
	++i;

    /*
     * Repeat to match several nested comment strings.
     */
    while (line[i])
    {
	/*
	 * scan through the 'comments' option for a match
	 */
	found_one = FALSE;
	for (list = curbuf->b_p_com; *list; )
	{
	    /*
	     * Get one option part into part_buf[].  Advance list to next one.
	     * put string at start of string.
	     */
	    if (!got_com && flags != NULL)  /* remember where flags started */
		*flags = list;
	    (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
	    string = vim_strchr(part_buf, ':');
	    if (string == NULL)	    /* missing ':', ignore this part */
		continue;
	    *string++ = NUL;	    /* isolate flags from string */

	    /*
	     * When already found a nested comment, only accept further
	     * nested comments.
	     */
	    if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
		continue;

	    /*
	     * Line contents and string must match.
	     */
	    for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
		;
	    if (string[j] != NUL)
		continue;

	    /*
	     * When 'b' flag used, there must be white space or an
	     * end-of-line after the string in the line.
	     */
	    if (vim_strchr(part_buf, COM_BLANK) != NULL &&
			      !vim_iswhite(line[i + j]) && line[i + j] != NUL)
		continue;

	    /*
	     * We have found a match, stop searching.
	     */
	    i += j;
	    got_com = TRUE;
	    found_one = TRUE;
	    break;
	}

	/*
	 * No match found, stop scanning.
	 */
	if (!found_one)
	    break;

	/*
	 * Include any trailing white space.
	 */
	while (vim_iswhite(line[i]))
	    ++i;

	/*
	 * If this comment doesn't nest, stop here.
	 */
	if (vim_strchr(part_buf, COM_NEST) == NULL)
	    break;
    }
    return (got_com ? i : 0);
}

/*
 * plines(p) - return the number of physical screen lines taken by line 'p'
 */
    int
plines(p)
    linenr_t	p;
{
    return plines_win(curwin, p);
}

    int
plines_win(wp, p)
    WIN		*wp;
    linenr_t	p;
{
    long	col;
    char_u	*s;
    int		lines;

    if (!wp->w_p_wrap)
	return 1;

    s = ml_get_buf(wp->w_buffer, p, FALSE);
    if (*s == NUL)		/* empty line */
	return 1;

    col = win_linetabsize(wp, s);

    /*
     * If list mode is on, then the '$' at the end of the line may take up one
     * extra column.
     */
    if (wp->w_p_list && lcs_eol != NUL)
	col += 1;

    /*
     * If 'number' mode is on, add another 8.
     */
    if (wp->w_p_nu)
	col += 8;

    lines = (col + (Columns - 1)) / Columns;
    if (lines <= wp->w_height)
	return lines;
    return (int)(wp->w_height);	    /* maximum length */
}

/*
 * Like plines_win(), but only reports the number of physical screen lines used
 * from the start of the line to the given column number.
 */
    int
plines_win_col(wp, p, column)
    WIN		*wp;
    linenr_t	p;
    long	column;
{
    register long	col;
    register char_u	*s;
    register int	lines;

    if (!wp->w_p_wrap)
	return 1;

    s = ml_get_buf(wp->w_buffer, p, FALSE);

    col = 0;
    while (*s != NUL && --column >= 0)
	col += win_lbr_chartabsize(wp, s++, (colnr_t)col, NULL);

    /*
     * If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
     * INSERT mode, then col must be adjusted so that it represents the last
     * screen position of the TAB.  This only fixes an error when the TAB wraps
     * from one screen line to the next (when 'columns' is not a multiple of
     * 'ts') -- webb.
     */
    if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
	col += win_lbr_chartabsize(wp, s, (colnr_t)col, NULL) - 1;

    /*
     * If 'number' mode is on, add another 8.
     */
    if (wp->w_p_nu)
	col += 8;

    lines = 1 + col / Columns;
    if (lines <= wp->w_height)
	return lines;
    return (int)(wp->w_height);	    /* maximum length */
}


/*
 * Count the physical lines (rows) for the lines "first" to "last" inclusive.
 */
    int
plines_m(first, last)
    linenr_t	    first, last;
{
    return plines_m_win(curwin, first, last);
}

    int
plines_m_win(wp, first, last)
    WIN		    *wp;
    linenr_t	    first, last;
{
    int count = 0;

    while (first <= last)
	count += plines_win(wp, first++);
    return (count);
}

/*
 * Insert or replace a single character at the cursor position.
 * When in REPLACE mode, replace any existing character.
 */
    void
ins_char(c)
    int		c;
{
    char_u	    *p;
    char_u	    *newp;
    char_u	    *oldp;

⌨️ 快捷键说明

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