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