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

📄 ex_getln.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
	    {
		msg_putchar('\n');
		break;
	    }

	    while (len > 0)
	    {
		c1 = *p++;
		--len;
# ifndef NO_COOKED_INPUT
		if ((c1 == K_SPECIAL || c1 == CSI) && len >= 2)
# else
#  ifdef USE_GUI
		if ((c1 == K_SPECIAL || (c1 == CSI && gui.in_use)) && len >= 2)
#  else
		if (c1 == K_SPECIAL && len >= 2)
#  endif
# endif
		{
		    c1 = TO_SPECIAL(p[0], p[1]);
		    p += 2;
		    len -= 2;
		}

		if (!escaped)
		{
		    if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL)
		    {
			if (line_ga.ga_len > 0)
			{
			    int		i, v;
			    char_u	*q;

			    --line_ga.ga_len;
			    ++line_ga.ga_room;
			    /* compute column that cursor should be in */
			    v = 0;
			    q = ((char_u *)line_ga.ga_data);
			    for (i = 0; i < line_ga.ga_len; ++i)
			    {
				if (*q == TAB)
				    v += 8 - v % 8;
				else
				    v += charsize(*q);
				++q;
			    }
			    /* erase characters to position cursor */
			    while (vcol > v)
			    {
				msg_putchar('\b');
				msg_putchar(' ');
				msg_putchar('\b');
				--vcol;
			    }
			}
			continue;
		    }

		    if (c1 == Ctrl('U'))
		    {
			msg_col = startcol;
			msg_clr_eos();
			line_ga.ga_room += line_ga.ga_len;
			line_ga.ga_len = 0;
			continue;
		    }

		    if (c1 == Ctrl('V'))
		    {
			escaped = TRUE;
			continue;
		    }
		}

		((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
		if (c1 == '\r')
		    msg_putchar('\n');
		else if (c1 == TAB)
		{
		    /* Don't use chartabsize(), 'ts' can be different */
		    do
		    {
			msg_putchar(' ');
		    } while (++vcol % 8);
		}
		else
		{
		    msg_outtrans_len(
			     ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
		    vcol += charsize(c1);
		}
		++line_ga.ga_len;
		--line_ga.ga_room;
		escaped = FALSE;
	    }
	    windgoto(msg_row, msg_col);
	}
# ifndef NO_COOKED_INPUT
	else
# endif
#endif
#ifndef NO_COOKED_INPUT
	{
	    line_ga.ga_len += len;
	    line_ga.ga_room -= len;
	}
#endif
	p = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
	while (line_ga.ga_len && (p[-1] == '\n' || p[-1] == '\r'))
	{
	    finished = TRUE;
	    --line_ga.ga_len;
	    --p;
	    *p = NUL;
	}
    }

    /* note that cursor has moved, because of the echoed <CR> */
    screen_down();
    /* make following messages go to the next line */
    msg_didout = FALSE;
    msg_col = 0;
    if (msg_row < Rows - 1)
	++msg_row;
    emsg_on_display = FALSE;		/* don't want ui_delay() */

    if (got_int)
	ga_clear(&line_ga);

    return (char_u *)line_ga.ga_data;
}

#ifdef CURSOR_SHAPE
/*
 * Return TRUE if ccline.overstrike is on.
 */
    int
cmdline_overstrike()
{
    return ccline.overstrike;
}

/*
 * Return TRUE if the cursor is at the end of the cmdline.
 */
    int
cmdline_at_end()
{
    return (ccline.cmdpos >= ccline.cmdlen);
}
#endif

/*
 * Allocate a new command line buffer.
 * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
 * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
 */
    static void
alloc_cmdbuff(len)
    int	    len;
{
    /*
     * give some extra space to avoid having to allocate all the time
     */
    if (len < 80)
	len = 100;
    else
	len += 20;

    ccline.cmdbuff = alloc(len);    /* caller should check for out-of-memory */
    ccline.cmdbufflen = len;
}

/*
 * Re-allocate the command line to length len + something extra.
 * return FAIL for failure, OK otherwise
 */
    static int
realloc_cmdbuff(len)
    int	    len;
{
    char_u	*p;

    p = ccline.cmdbuff;
    alloc_cmdbuff(len);			/* will get some more */
    if (ccline.cmdbuff == NULL)		/* out of memory */
    {
	ccline.cmdbuff = p;		/* keep the old one */
	return FAIL;
    }
    mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
    vim_free(p);
    return OK;
}

/*
 * put a character on the command line.
 * Used for CTRL-V and CTRL-K
 */
    static void
putcmdline(c)
    int	    c;
{
    char_u  buf[1];

    buf[0] = c;
    msg_outtrans_len(buf, 1);
    msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
					       ccline.cmdlen - ccline.cmdpos);
    cursorcmd();
}

/*
 * Put the given string, of the given length, onto the command line.
 * If len is -1, then STRLEN() is used to calculate the length.
 * If 'redraw' is TRUE then the new part of the command line, and the remaining
 * part will be redrawn, otherwise it will not.  If this function is called
 * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
 * called afterwards.
 */
    int
put_on_cmdline(str, len, redraw)
    char_u  *str;
    int	    len;
    int	    redraw;
{
    int	    i;

    if (len < 0)
	len = STRLEN(str);

    /* Check if ccline.cmdbuff needs to be longer */
    if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
	i = realloc_cmdbuff(ccline.cmdlen + len);
    else
	i = OK;
    if (i == OK)
    {
	if (!ccline.overstrike)
	{
	    mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
					       ccline.cmdbuff + ccline.cmdpos,
				     (size_t)(ccline.cmdlen - ccline.cmdpos));
	    ccline.cmdlen += len;
	}
	else if (ccline.cmdpos + len > ccline.cmdlen)
	    ccline.cmdlen = ccline.cmdpos + len;
	mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
	if (redraw)
	    msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
					       ccline.cmdlen - ccline.cmdpos);
#ifdef FKMAP
	/*
	 ** If we are in Farsi command mode, the character input must be in
	 ** insert mode. So do not advance the cmdpos.
	 */
	if (!cmd_fkmap)
#endif
	{
	    ccline.cmdpos += len;
	    while (len--)
		ccline.cmdspos += charsize(str[len]);
	}
    }
    if (redraw)
	msg_check();
    return i;
}

/*
 * this fuction is called when the screen size changes and with incremental
 * search
 */
    void
redrawcmdline()
{
    msg_scrolled = 0;
    need_wait_return = FALSE;
    compute_cmdrow();
    redrawcmd();
    cursorcmd();
}

    static void
redrawcmdprompt()
{
    int		i;

    if (ccline.cmdfirstc)
	msg_putchar(ccline.cmdfirstc);
    if (ccline.cmdprompt != NULL)
    {
	msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
	ccline.cmdindent = msg_col;
    }
    else
	for (i = ccline.cmdindent; i > 0; --i)
	    msg_putchar(' ');
}

/*
 * Redraw what is currently on the command line.
 */
    static void
redrawcmd()
{
    int	    i;

    msg_start();
    redrawcmdprompt();
    msg_outtrans_len(ccline.cmdbuff, ccline.cmdlen);
    msg_clr_eos();

    set_cmdspos();
    for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
	ccline.cmdspos += charsize(ccline.cmdbuff[i]);
    /*
     * An emsg() before may have set msg_scroll. This is used in normal mode,
     * in cmdline mode we can reset them now.
     */
    msg_scroll = FALSE;		/* next message overwrites cmdline */

    /* Typing ':' at the more prompt may set skip_redraw.  We don't want this
     * in cmdline mode */
    skip_redraw = FALSE;
}

/*
 * Set prompt in front of cmdline.
 */
    void
cmdline_prompt(cmsg, attr)
    char_u	*cmsg;
    int		attr;
{
    ccline.cmdprompt = cmsg;
    ccline.cmdattr = attr;
}

    void
compute_cmdrow()
{
    if (exmode_active)
	cmdline_row = Rows - 1;
    else
	cmdline_row = lastwin->w_winpos + lastwin->w_height +
					lastwin->w_status_height;
}

    static void
cursorcmd()
{
    msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
    msg_col = ccline.cmdspos % (int)Columns;
    if (msg_row >= Rows)
	msg_row = Rows - 1;
    windgoto(msg_row, msg_col);
#if defined(MSDOS) || (defined(WIN32) && !defined(USE_GUI_WIN32))
    mch_update_cursor();
#endif
}

    void
gotocmdline(clr)
    int		    clr;
{
    msg_start();
    msg_col = 0;	    /* always start in column 0 */
    if (clr)		    /* clear the bottom line(s) */
	msg_clr_eos();	    /* will reset clear_cmdline */
    windgoto(cmdline_row, 0);
}

/*
 * Check the word in front of the cursor for an abbreviation.
 * Called when the non-id character "c" has been entered.
 * When an abbreviation is recognized it is removed from the text with
 * backspaces and the replacement string is inserted, followed by "c".
 */
    static int
ccheck_abbr(c)
    int c;
{
    if (p_paste || no_abbr)	    /* no abbreviations or in paste mode */
	return FALSE;

    return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
}

/*
 * Return FAIL if this is not an appropriate context in which to do
 * completion of anything, return OK if it is (even if there are no matches).
 * For the caller, this means that the character is just passed through like a
 * normal character (instead of being expanded).  This allows :s/^I^D etc.
 */
    static int
nextwild(type, options)
    int	    type;
    int	    options;	    /* extra options for ExpandOne() */
{
    int	    i, j;
    char_u  *p1;
    char_u  *p2;
    int	    oldlen;
    int	    difflen;
    int	    v;

    if (cmd_numfiles == -1)
	set_expand_context();
    if (expand_context == EXPAND_UNSUCCESSFUL)
    {
	beep_flush();
	return OK;  /* Something illegal on command line */
    }
    if (expand_context == EXPAND_NOTHING)
    {
	/* Caller can use the character as a normal char instead */
	return FAIL;
    }
    expand_interactively = TRUE;

    MSG_PUTS("...");	    /* show that we are busy */
    out_flush();

    i = expand_pattern - ccline.cmdbuff;
    oldlen = ccline.cmdpos - i;

    if (type == WILD_NEXT || type == WILD_PREV)
    {
	/*
	 * Get next/previous match for a previous expanded pattern.
	 */
	p2 = ExpandOne(NULL, NULL, 0, type);
    }
    else
    {
	/*
	 * Translate string into pattern and expand it.
	 */
	if ((p1 = addstar(&ccline.cmdbuff[i], oldlen)) == NULL)
	    p2 = NULL;
	else
	{
	    p2 = ExpandOne(p1, vim_strnsave(&ccline.cmdbuff[i], oldlen),
					   WILD_HOME_REPLACE | options, type);
	    vim_free(p1);
	    /* longest match: make sure it is not shorter (happens with :help */
	    if (p2 != NULL && type == WILD_LONGEST)
	    {
		for (j = 0; j < oldlen; ++j)
		     if (ccline.cmdbuff[i + j] == '*'
			     || ccline.cmdbuff[i + j] == '?')
			 break;
		if ((int)STRLEN(p2) < j)
		{
		    vim_free(p2);
		    p2 = NULL;
		}
	    }
	}
    }

    if (p2 != NULL)
    {
	if (ccline.cmdlen + (difflen = STRLEN(p2) - oldlen) >
							ccline.cmdbufflen - 4)
	{
	    v = realloc_cmdbuff(ccline.cmdlen + difflen);
	    expand_pattern = ccline.cmdbuff + i;
	}
	else
	    v = OK;
	if (v == OK)
	{
	    vim_strncpy(&ccline.cmdbuff[ccline.cmdpos + difflen],
					       &ccline.cmdbuff[ccline.cmdpos],
		    ccline.cmdlen - ccline.cmdpos);
	    STRNCPY(&ccline.cmdbuff[i], p2, STRLEN(p2));
	    ccline.cmdlen += difflen;
	    ccline.cmdpos += difflen;
	}
	vim_free(p2);
    }

    redrawcmd();
    if (cmd_numfiles <= 0 && p2 == NULL)
	beep_flush();
    else if (cmd_numfiles == 1)
	(void)ExpandOne(NULL, NULL, 0, WILD_FREE);  /* free expanded pattern */

    expand_interactively = FALSE;	    /* reset for next call */
    return OK;
}

/*
 * Do wildcard expansion on the string 'str'.
 * Return a pointer to alloced memory containing the new string.
 * Return NULL for failure.
 *
 * mode = WILD_FREE:	    just free previously expanded matches
 * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
 * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
 * mode = WILD_NEXT:	    use next match in multiple match, wrap to first
 * mode = WILD_PREV:	    use previous match in multiple match, wrap to first
 * mode = WILD_ALL:	    return all matches concatenated
 * mode = WILD_LONGEST:	    return longest matched part
 *
 * options = WILD_LIST_NOTFOUND:    list entries without a match
 * options = WILD_HOME_REPLACE:	    do home_replace() for buffer names
 * options = WILD_USE_NL:	    Use '\n' for WILD_ALL
 * options = WILD_NO_BEEP:	    Don't beep for multiple matches
 */
    char_u *
ExpandOne(str, orig, options, mode)
    char_u  *str;
    char_u  *orig;	    /* original string which is expanded */

⌨️ 快捷键说明

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