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

📄 edit.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
	    done_info = 0;
	    while (*e_cpt == ',' || *e_cpt == ' ')
		e_cpt++;
	    if (*e_cpt == '.' && !curbuf->b_scanned)
	    {
		ins_buf = curbuf;
		first_match_pos = *ini;
		/* So that ^N can match word immediately after cursor */
		if (ctrl_x_mode == 0)
		    dec(&first_match_pos);
		last_match_pos = first_match_pos;
		type = 0;
	    }
	    else if (vim_strchr((char_u *)"buw", *e_cpt) != NULL
		    && (ins_buf = next_buf(ins_buf, *e_cpt)) != curbuf)
	    {
		if (*e_cpt != 'u')
		{
		    started_completion = TRUE;
		    first_match_pos.col = last_match_pos.col = 0;
		    first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1;
		    last_match_pos.lnum = 0;
		    type = 0;
		}
		else
		{
		    done_info = 6;
		    if (ins_buf->b_fname == NULL)
			continue;
		    type = CTRL_X_DICTIONARY;
		    dict = ins_buf->b_fname;
		    dict_f = DICT_EXACT;
		}
		sprintf((char*)IObuff, "Scanning: %s",
			ins_buf->b_sfname == NULL ? "No File"
						  : (char *)ins_buf->b_sfname);
		msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
	    }
	    else if (*e_cpt == NUL)
		break;
	    else
	    {
		if (*e_cpt == 'k')
		{
		    type = CTRL_X_DICTIONARY;
		    if (*++e_cpt != ',' && *e_cpt != NUL)
		    {
			dict = e_cpt;
			dict_f = DICT_FIRST;
		    }
		}
#ifdef FIND_IN_PATH
		else if (*e_cpt == 'i')
		    type = CTRL_X_PATH_PATTERNS;
#endif
		else if (*e_cpt == ']' || *e_cpt == 't')
		{
		    type = CTRL_X_TAGS;
		    sprintf((char*)IObuff, "Scanning tags.");
		    msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
		}
		else
		    type = -1;

		/* in any case e_cpt is advanced to the next entry */
		(void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");

		done_info = 6;
		if (type == -1)
		    continue;
	    }
	}

	switch (type)
	{
	case -1:
	    break;
#ifdef FIND_IN_PATH
	case CTRL_X_PATH_PATTERNS:
	case CTRL_X_PATH_DEFINES:
	    find_pattern_in_path(complete_pat, dir,
				 (int)STRLEN(complete_pat), FALSE, FALSE,
				 (type == CTRL_X_PATH_DEFINES
				  && !(continue_status & CONT_SOL))
				 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
				 (linenr_t)1, (linenr_t)MAXLNUM);
	    break;
#endif

	case CTRL_X_DICTIONARY:
	    complete_dictionaries(dict ? dict : p_dict, complete_pat, dir,
				  dict ? dict_f : 0);
	    dict = NULL;
	    break;

	case CTRL_X_TAGS:
	    /* set reg_ic according to p_ic, p_scs and pat */
	    set_reg_ic(complete_pat);
	    if (find_tags(complete_pat, &temp, &matches,
		    TAG_REGEXP | TAG_NAMES | (ctrl_x_mode ? TAG_VERBOSE : 0),
						    MAXCOL) == OK && temp > 0)
	    {
		int	add_r = OK;
		int	ldir = dir;

		for (i = 0; i < temp && add_r != RET_ERROR; i++)
		    if ((add_r = add_completion(matches[i], -1, NULL, ldir, 0))
			    == OK)
			/* if dir was BACKWARD then honor it just once */
			ldir = FORWARD;
		FreeWild(temp, matches);
	    }
	    break;

	case CTRL_X_FILES:
	    expand_interactively = TRUE;
	    if (expand_wildcards(1, &complete_pat, &temp, &matches,
							EW_FILE|EW_DIR) == OK)
	    {
		int	add_r = OK;
		int	ldir = dir;

		/* May change home directory back to "~". */
		tilde_replace(complete_pat, temp, matches);
		for (i = 0; i < temp && add_r != RET_ERROR; i++)
		    if ((add_r = add_completion(matches[i], -1, NULL, ldir, 0))
			    == OK)
			/* if dir was BACKWARD then honor it just once */
			ldir = FORWARD;
		FreeWild(temp, matches);
	    }
	    expand_interactively = FALSE;
	    break;

	default:	/* normal ^P/^N and ^X^L */
	    /*
	     * If 'infercase' is set, don't use 'smartcase' here
	     */
	    save_p_scs = p_scs;
	    if (ins_buf->b_p_inf)
		p_scs = FALSE;
	    /*	buffers other than curbuf are scanned from the beginning or the
	     *	end but never from the middle, thus setting nowrapscan in this
	     *	buffers is a good idea -- Acevedo */
	    save_p_ws = p_ws;
	    if (ins_buf != curbuf)
		p_ws = FALSE;
	    for (;;)
	    {
		int	reuse = 0;

		/* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that has
		 * added a word that was at the beginning of the line */
		if (	ctrl_x_mode == CTRL_X_WHOLE_LINE
			|| (continue_status & CONT_SOL))
		    temp = search_for_exact_line(ins_buf, pos,
							   dir, complete_pat);
		else
		    temp = searchit(ins_buf, pos, dir, complete_pat, 1L,
				    SEARCH_KEEP + SEARCH_NFMSG, RE_LAST);
		if (!started_completion)
		{
		    /* set started_completion even on fail */
		    started_completion = TRUE;
		    first_match_pos = *pos;
		    last_match_pos = *pos;
		}
		else if (first_match_pos.lnum == last_match_pos.lnum
			 && first_match_pos.col == last_match_pos.col)
		    temp = FAIL;
		if (   temp == FAIL && ins_buf == curbuf
		       && (done_info |= p_ws ? 6 : dir + 3) < 6)
		    /* With nowrapscan, we haven't finished looking in the
		     * other direction yet -- webb */
		    temp = -OK;
		if (temp != OK)
		    break;

		/* when ADDING, the text before the cursor matches, skip it */
		if (	(continue_status & CONT_ADDING) && ins_buf == curbuf
			&& ini->lnum == pos->lnum
			&& ini->col  == pos->col)
		    continue;
		ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col;
		if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
		{
		    if (continue_status & CONT_ADDING)
		    {
			if (pos->lnum >= ins_buf->b_ml.ml_line_count)
			    continue;
			ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
			if (!p_paste)
			    ptr = skipwhite(ptr);
		    }
		    temp = STRLEN(ptr);
		}
		else
		{
		    tmp_ptr = ptr;
		    if (continue_status & CONT_ADDING)
		    {
			tmp_ptr += completion_length;
			if (vim_iswordc(*tmp_ptr))
			    continue;
			while (*tmp_ptr && !vim_iswordc(*tmp_ptr++))
			    ;
		    }
		    while (vim_iswordc(*tmp_ptr))
			tmp_ptr++;
		    temp = tmp_ptr - ptr;
		    if ((continue_status & CONT_ADDING)
			&& temp == completion_length)
		    {
			if (pos->lnum < ins_buf->b_ml.ml_line_count)
			{
			    /* Try next line, if any. the new word will be
			     * "join" as if the normal command "J" was used.
			     * IOSIZE is always greater than
			     * completion_length, so the next STRNCPY always
			     * works -- Acevedo */
			    STRNCPY(IObuff, ptr, temp);
			    ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
			    tmp_ptr = ptr = skipwhite(ptr);
			    while (*tmp_ptr && !vim_iswordc(*tmp_ptr++))
				;
			    while (vim_iswordc(*tmp_ptr))
				tmp_ptr++;
			    if (tmp_ptr > ptr)
			    {
				if (*ptr != ')' && IObuff[temp-1] != TAB)
				{
				    if (IObuff[temp-1] != ' ')
					IObuff[temp++] = ' ';
				    /* IObuf =~ "\k.* ", thus temp >= 2 */
				    if (p_js
					&& (IObuff[temp-2] == '.'
					    || (vim_strchr(p_cpo, CPO_JOINSP)
								       == NULL
						&& (IObuff[temp-2] == '?'
						    || IObuff[temp-2] == '!'))))
					IObuff[temp++] = ' ';
				}
				/* copy as much as posible of the new word */
				if (tmp_ptr - ptr >= IOSIZE - temp)
				    tmp_ptr = ptr + IOSIZE - temp - 1;
				STRNCPY(IObuff + temp, ptr, tmp_ptr - ptr);
				temp += tmp_ptr - ptr;
				reuse |= CONT_S_IPOS;
			    }
			    IObuff[temp] = NUL;
			    ptr = IObuff;
			}
			if (temp == completion_length)
			    continue;
		    }
		}
		if (add_completion_and_infercase(ptr, temp, ins_buf == curbuf ?
			NULL : ins_buf->b_sfname, dir, reuse) != FAIL)
		{
		    temp = OK;
		    break;
		}
	    }
	    p_scs = save_p_scs;
	    p_ws = save_p_ws;
	}
	/* check if curr_match has changed, (e.g. other type of expansion
	 * added somenthing) */
	if (curr_match != old_match)
	    temp = OK;
	/* break the loop for specialized modes (use 'complete' just for the
	 * generic ctrl_x_mode == 0) and when temp != FAIL */
	if (ctrl_x_mode || temp)
	    break;
	if (type == 0 || type == CTRL_X_PATH_PATTERNS)
	    ins_buf->b_scanned = TRUE;

	started_completion = FALSE;
    }
    started_completion = TRUE;

    i = -1;		/* total of matches, unknown */
    if (temp == FAIL || (ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE))
	i = make_cyclic();
    else if (temp == -OK && (curr_match->original & ORIGINAL_TEXT))
    {
	edit_submode_extra = (continue_status & CONT_ADDING)
	    && completion_length > 1
		? (dir == FORWARD ? e_hitend_f : e_hitend_b)
		: (dir == FORWARD ? e_patnotf_f : e_patnotf_b);
	edit_submode_highl = HLF_E;
    }
    /* If several matches were added (FORWARD) or the search failed and has
     * just been made cyclic then we have to move curr_match to the next or
     * previous entry (if any, when search failed with 'nows') -- Acevedo */
    curr_match = dir == FORWARD ? old_match->next : old_match->prev;
    if (curr_match == NULL)
	curr_match = old_match;
    return i;
}

    static int
ins_complete(c)
    int		    c;
{
    int		    complete_direction;
    char_u	    *ptr;
    char_u	    *tmp_ptr = NULL;		/* init for gcc */
    static colnr_t  complete_col = 0;		/* init for gcc */
    int		    temp = 0;
    int		    i;
    int		    cc;
    static FPOS	    initial_pos;

    if (c == Ctrl('P') || c == Ctrl('L'))
	complete_direction = BACKWARD;
    else
	complete_direction = FORWARD;
    if (!started_completion)
    {
	/* First time we hit ^N or ^P (in a row, I mean) */

	/* Turn off 'sm' so we don't show matches with ^X^L */
	save_sm = p_sm;
	p_sm = FALSE;

	did_ai = FALSE;
#ifdef SMARTINDENT
	did_si = FALSE;
	can_si = FALSE;
	can_si_back = FALSE;
#endif
	stop_arrow();
	ptr = ml_get(curwin->w_cursor.lnum);
	complete_col = curwin->w_cursor.col;

	/* if this same ctrl_x_mode has been interrupted use the text from
	 * initial_pos to the cursor as a pattern to add a new word instead of
	 * expand the one before the cursor, in word-wise if "initial_pos" is
	 * not in the same line as the cursor then fix it (the line has been
	 * split because it was longer than 'tw').  if SOL is set then skip
	 * the previous pattern, a word at the beginning of the line has been
	 * inserted, we'll look for that  -- Acevedo. */
	if ((continue_status & CONT_INTRPT) && continue_mode == ctrl_x_mode)
	{	/* it is a continued search */
	    continue_status &= ~CONT_INTRPT;	/* remove INTRPT */
	    if (ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_PATH_PATTERNS
					|| ctrl_x_mode == CTRL_X_PATH_DEFINES)
	    {
		if (initial_pos.lnum != curwin->w_cursor.lnum)
		{
		    /* line (probably) wrapped, set initial_pos to the first
		     * non_blank in the line, if it is not a wordchar include
		     * it to get a better pattern, but then we don't want the
		     * "\\<" prefix, check it bellow */
		    tmp_ptr = skipwhite(ptr);
		    initial_pos.col = tmp_ptr - ptr;
		    initial_pos.lnum = curwin->w_cursor.lnum;
		    continue_status &= ~CONT_SOL;    /* clear SOL if present */
		}
		else
		{
		    /* S_IPOS was set when we inserted a word that was at the
		     * beginning of the line, which means that we'll go to SOL
		     * mode but first we need to redefine initial_pos */
		    if (continue_status & CONT_S_IPOS)
		    {
			continue_status |= CONT_SOL;
			initial_pos.col = skipwhite(ptr + completion_length +
						    initial_pos.col) - ptr;
		    }
		    tmp_ptr = ptr + initial_pos.col;
		}
		temp = curwin->w_cursor.col - (tmp_ptr-ptr);
		/* IObuf is used to add a "word from the next line" would we
		 * have enough space?  just being paranoic */
#define	MIN_SPACE 75
		if (temp > (IOSIZE - MIN_SPACE))
		{
		    continue_status &= ~CONT_SOL;
		    temp = (IOSIZE - MIN_SPACE);
		    tmp_ptr = curwin->w_cursor.col - temp + ptr;
		}
		continue_status |= CONT_ADDING | CONT_N_ADDS;
		if (temp < 1)
		    continue_status &= CONT_LOCAL;
	    }
	    else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
		continue_status = CONT_ADDING | CONT_N_ADDS;
	    else
		continue_status = 0;
	}
	else
	    continue_status &= CONT_LOCAL;

	if (!(continue_status & CONT_ADDING))	/* normal expansion */
	{
	    continue_mode = ctrl_x_mode;
	    if (ctrl_x_mode)	/* Remove LOCAL iff ctrl_x_mode != 0 */
		continue_status = 0;
	    continue_status |= CONT_N_ADDS;
	    initial_pos = curwin->w_cursor;
	    temp = (int)complete_col;
	    tmp_ptr = ptr;
	}

	/* Work out completion pattern and original text -- webb */
	if (ctrl_x_mode == 0 || (ctrl_x_mode & CTRL_X_WANT_IDENT))
	{
	    if (       (continue_status & CONT_SOL)
		    || ctrl_x_mode == CTRL_X_PATH_DEFINES)
	    {
		if (!(continue_status & CONT_ADDING))
		{
		    while (--temp >= 0 && vim_isIDc(ptr[temp]))
			;
		    tmp_ptr += ++temp;
		    temp = complete_col - temp;
		}
		complete_pat = vim_strnsave(tmp_ptr, temp);
		if (complete_pat == NULL)
		    return FALSE;
		if (p_ic)
		    for (i = 0; i < temp; i++)
			complete_pat[i] = TO_LOWER(complete_pat[i]);
	    }
	    else if (continue_status & CONT_ADDING)
	    {
		char_u	    *prefix = (char_u *)"\\<";

		/* we need 3 extra chars, 1 for the NUL and
		 * 2 >= strlen(prefix)	-- Acevedo */
		complete_pat = alloc(quote_meta(NULL, tmp_ptr, temp) + 3);
		if (complete_pat == NULL)
		    return FALSE;
		if (!vim_iswordc(*tmp_ptr) ||
			(tmp_ptr > ptr && vim_iswordc(*(tmp_ptr-1))))
		    prefix = (char_u *)"";
		STRCPY((char *)complete_pat, prefix);
		(void)quote_meta(complete_pat + STRLEN(prefix), tmp_ptr, temp);
	    }
	    else if (--temp < 0 || !vim_iswordc(ptr[temp]))
	    {
		/* Match any word of at least two chars */
		complete_pat = vim_strsave((char_u *)"\\<\\k\\k");
		if (complete_pat == NULL)
		    return FALSE;
		tmp_ptr += complete_col;
		temp = 0;
	    }
	    else
	    {
		while (--temp >= 0 && vim_iswordc(ptr[temp]))
		    ;
		tmp_ptr += ++temp;
		if ((temp = (int)complete_col - temp) == 1)
		{
		    /* Only match word with at least two chars -- webb
		     * there's no need to call quote_meta,
		     * alloc(7) is enough  -- Acevedo
		     */
		    complete_pat = alloc(7);
		    if (complete_pat == NULL)
			return FALSE;
		    STRCPY((char *)complete_pat, "\\<");
		    (void)quote_meta(complete_pat + 2, tmp_ptr, 1);
		    STRCAT((char *)complete_pat, "\\k");
		}
		else
		{
		    complete_pat = alloc(quote_meta(NULL, tmp_ptr, temp) + 3);
		    if (complete_pat == NULL)
			return FALSE;
		    STRCPY((char *)complete_pat, "\\<");
		    (void)quote_meta(complete_pat + 2, tmp_ptr, temp);
		}
	    }
	}
	else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
	{
	    tmp_ptr = skipwhite(ptr);
	    temp = (int)complete_col - (tmp_ptr - ptr);
	    complete_pat = vim_strnsave(tmp_ptr, temp);
	    if (complete_pat == NULL)
		return FALSE;
	    if (p_ic)
		for (i = 0; 

⌨️ 快捷键说明

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