📄 ex_cmds.c
字号:
prepare_viminfo_history(forceit ? 9999 : 0);
eof = vim_fgets(line, LSIZE, fp);
while (!eof && line[0] != '>')
{
switch (line[0])
{
/* Characters reserved for future expansion, ignored now */
case '+': /* "+40 /path/dir file", for running vim without args */
case '|': /* to be defined */
case '-': /* to be defined */
case '!': /* to be defined */
case '^': /* to be defined */
case '*': /* to be defined */
case '<': /* to be defined */
/* A comment */
case NUL:
case '\r':
case '\n':
case '#':
eof = vim_fgets(line, LSIZE, fp);
break;
case '%': /* entry for buffer list */
eof = read_viminfo_bufferlist(line, fp, writing);
break;
case '"':
eof = read_viminfo_register(line, fp, forceit);
break;
case '/': /* Search string */
case '&': /* Substitute search string */
case '~': /* Last search string, followed by '/' or '&' */
eof = read_viminfo_search_pattern(line, fp, forceit);
break;
case '$':
eof = read_viminfo_sub_string(line, fp, forceit);
break;
case ':':
case '?':
case '=':
case '@':
eof = read_viminfo_history(line, fp);
break;
case '\'':
/* How do we have a file mark when the file is not in the
* buffer list?
*/
eof = read_viminfo_filemark(line, fp, forceit);
break;
default:
if (viminfo_error("Illegal starting char", line))
eof = TRUE;
else
eof = vim_fgets(line, LSIZE, fp);
break;
}
}
finish_viminfo_history();
return eof;
}
/*
* check string read from viminfo file
* remove '\n' at the end of the line
* - replace CTRL-V CTRL-V with CTRL-V
* - replace CTRL-V 'n' with '\n'
*/
void
viminfo_readstring(p)
char_u *p;
{
while (*p != NUL && *p != '\n')
{
if (*p == Ctrl('V'))
{
if (p[1] == 'n')
p[0] = '\n';
mch_memmove(p + 1, p + 2, STRLEN(p));
}
++p;
}
*p = NUL;
}
/*
* write string to viminfo file
* - replace CTRL-V with CTRL-V CTRL-V
* - replace '\n' with CTRL-V 'n'
* - add a '\n' at the end
*/
void
viminfo_writestring(fd, p)
FILE *fd;
char_u *p;
{
int c;
while ((c = *p++) != NUL)
{
if (c == Ctrl('V') || c == '\n')
{
putc(Ctrl('V'), fd);
if (c == '\n')
c = 'n';
}
putc(c, fd);
}
putc('\n', fd);
}
#endif /* VIMINFO */
/*
* Implementation of ":fixdel", also used by get_stty().
* <BS> resulting <Del>
* ^? ^H
* not ^? ^?
*/
void
do_fixdel()
{
char_u *p;
p = find_termcode((char_u *)"kb");
add_termcode((char_u *)"kD", p != NULL && *p == 0x7f ?
(char_u *)"\010" : (char_u *)"\177");
}
void
print_line_no_prefix(lnum, use_number)
linenr_t lnum;
int use_number;
{
char_u numbuf[20];
if (curwin->w_p_nu || use_number)
{
sprintf((char *)numbuf, "%7ld ", (long)lnum);
msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */
}
msg_prt_line(ml_get(lnum));
}
/*
* Print a text line. Also in silent mode ("ex -s").
*/
void
print_line(lnum, use_number)
linenr_t lnum;
int use_number;
{
int save_silent = silent_mode;
silent_mode = FALSE;
msg_start();
print_line_no_prefix(lnum, use_number);
if (save_silent)
{
msg_putchar('\n');
cursor_on(); /* msg_start() switches it off */
out_flush();
silent_mode = save_silent;
}
}
/*
* Implementation of ":file[!] [fname]".
*/
void
do_file(arg, forceit)
char_u *arg;
int forceit;
{
char_u *fname, *sfname, *xfname;
BUF *buf;
if (*arg != NUL)
{
#ifdef AUTOCMD
buf = curbuf;
apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
/* buffer changed, don't change name now */
if (buf != curbuf)
return;
#endif
/*
* The name of the current buffer will be changed.
* A new buffer entry needs to be made to hold the old
* file name, which will become the alternate file name.
*/
fname = curbuf->b_ffname;
sfname = curbuf->b_sfname;
xfname = curbuf->b_fname;
curbuf->b_ffname = NULL;
curbuf->b_sfname = NULL;
if (setfname(arg, NULL, TRUE) == FAIL)
{
curbuf->b_ffname = fname;
curbuf->b_sfname = sfname;
return;
}
curbuf->b_notedited = TRUE;
buf = buflist_new(fname, xfname, curwin->w_cursor.lnum, FALSE);
if (buf != NULL)
curwin->w_alt_fnum = buf->b_fnum;
vim_free(fname);
vim_free(sfname);
#ifdef AUTOCMD
apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
#endif
}
/* print full file name if :cd used */
fileinfo(FALSE, FALSE, forceit);
}
/*
* Do the Ex mode :insert and :append commands.
* "getline" can be NULL, in which case a line is obtained from the user.
*/
void
do_append(lnum, getline, cookie)
linenr_t lnum;
char_u *(*getline) __ARGS((int, void *, int));
void *cookie; /* argument for getline() */
{
char_u *theline;
int did_undo = FALSE;
int lfirst = lnum;
State = INSERT; /* behave like in Insert mode */
while (1)
{
msg_scroll = TRUE;
need_wait_return = FALSE;
if (getline == NULL)
theline = getcmdline(NUL, 0L, 0);
else
theline = getline(NUL, cookie, 0);
lines_left = Rows - 1;
if (theline == NULL || (theline[0] == '.' && theline[1] == NUL))
break;
if (!did_undo && u_save(lnum, lnum + 1) == FAIL)
break;
did_undo = TRUE;
mark_adjust(lnum + 1, (linenr_t)MAXLNUM, 1L, 0L);
ml_append(lnum, theline, (colnr_t)0, FALSE);
changed();
vim_free(theline);
++lnum;
}
State = NORMAL;
/* "start" is set to lfirst+1 unless that position is invalid (when
* lfirst pointed to the end of the buffer and nothig was appended)
* "end" is set to lnum when something has been appended, otherwise
* it is the same than "start" -- Acevedo */
curbuf->b_op_start.lnum = (lfirst < curbuf->b_ml.ml_line_count) ?
lfirst + 1 : curbuf->b_ml.ml_line_count;
curbuf->b_op_end.lnum = (lfirst < lnum) ? lnum : curbuf->b_op_start.lnum;
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
curwin->w_cursor.lnum = lnum;
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
changed_line_abv_curs();
invalidate_botline();
dont_wait_return = TRUE; /* don't use wait_return() now */
need_wait_return = FALSE;
update_screen(NOT_VALID);
}
/*
* Do the Ex mode :change command.
* "getline" can be NULL, in which case a line is obtained from the user.
*/
void
do_change(start, end, getline, cookie)
linenr_t start;
linenr_t end;
char_u *(*getline) __ARGS((int, void *, int));
void *cookie; /* argument for getline() */
{
if (end >= start && u_save(start - 1, end + 1) == FAIL)
return;
mark_adjust(start, end, (long)MAXLNUM, (long)(start - end - 1));
while (end >= start)
{
if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
break;
ml_delete(start, FALSE);
changed();
end--;
}
do_append(start - 1, getline, cookie);
}
void
do_z(line, arg)
linenr_t line;
char_u *arg;
{
char_u *x;
int bigness = curwin->w_height - 3;
char_u kind;
int minus = 0;
linenr_t start, end, curs, i;
if (bigness < 1)
bigness = 1;
x = arg;
if (*x == '-' || *x == '+' || *x == '=' || *x == '^' || *x == '.')
x++;
if (*x != 0)
{
if (!isdigit(*x))
{
EMSG("non-numeric argument to :z");
return;
}
else
bigness = atoi((char *)x);
}
kind = *arg;
switch (kind)
{
case '-':
start = line - bigness;
end = line;
curs = line;
break;
case '=':
start = line - bigness / 2 + 1;
end = line + bigness / 2 - 1;
curs = line;
minus = 1;
break;
case '^':
start = line - bigness * 2;
end = line - bigness;
curs = line - bigness;
break;
case '.':
start = line - bigness / 2;
end = line + bigness / 2;
curs = end;
break;
default: /* '+' */
start = line;
end = line + bigness;
curs = end;
break;
}
if (start < 1)
start = 1;
if (end > curbuf->b_ml.ml_line_count)
end = curbuf->b_ml.ml_line_count;
if (curs > curbuf->b_ml.ml_line_count)
curs = curbuf->b_ml.ml_line_count;
for (i = start; i <= end; i++)
{
int j;
if (minus && (i == line))
{
msg_putchar('\n');
for (j = 1; j < Columns; j++)
msg_putchar('-');
}
print_line(i, FALSE);
if (minus && (i == line))
{
msg_putchar('\n');
for (j = 1; j < Columns; j++)
msg_putchar('-');
}
}
curwin->w_cursor.lnum = curs;
}
/*
* Check if the restricted flag is set.
* If so, give an error message and return TRUE.
* Otherwise, return FALSE.
*/
int
check_restricted()
{
if (restricted)
{
EMSG("Shell commands not allowed in rvim");
return TRUE;
}
return FALSE;
}
/*
* Check if the secure flag is set (.exrc or .vimrc in current directory).
* If so, give an error message and return TRUE.
* Otherwise, return FALSE.
*/
int
check_secure()
{
if (secure)
{
secure = 2;
emsg(e_curdir);
return TRUE;
}
return FALSE;
}
static char_u *old_sub = NULL; /* previous substitute pattern */
/*
* When ":global" is used to number of substitutions and changed lines is
* accumulated until it's finished.
*/
static long sub_nsubs; /* total number of substitutions */
static linenr_t sub_nlines; /* total number of lines changed */
/* do_sub()
*
* Perform a substitution from line eap->line1 to line eap->line2 using the
* command pointed to by eap->arg which should be of the form:
*
* /pattern/substitution/{flags}
*
* The usual escapes are supported as described in the regexp docs.
*/
void
do_sub(eap)
EXARG *eap;
{
linenr_t lnum;
long i;
char_u *ptr;
char_u *old_line;
vim_regexp *prog;
static int do_all = FALSE; /* do multiple substitutions per line */
static int do_ask = FALSE; /* ask for confirmation */
int do_error = TRUE; /* if false, ignore errors */
int do_print = FALSE; /* print last line with subst. */
int do_ic = 0; /* ignore case flag */
char_u *pat = NULL, *sub = NULL; /* init for GCC */
int delimiter;
int sublen;
int got_quit = FALSE;
int got_match = FALSE;
int temp;
int which_pat;
char_u *cmd;
int save_reg_ic;
int save_State;
cmd = eap->arg;
if (!global_busy)
{
sub_nsubs = 0;
sub_nlines = 0;
}
#ifdef FKMAP /* reverse the flow of the Farsi characters */
if (p_altkeymap && curwin->w_p_rl)
lrF_sub(cmd);
#endif
if (eap->cmdidx == CMD_tilde)
which_pat = RE_LAST; /* use last used regexp */
else
which_pat = RE_SUBST; /* use last substitute regexp */
/* new pattern and substitution */
if (eap->cmd[0] == 's' && *cmd != NUL && !vim_iswhite(*cmd)
&& vim_strchr((char_u *)"0123456789gcr|\"", *cmd) == NULL)
{
/* don't accept alphanumeric for separator */
if (isalpha(*cmd))
{
EMSG("Regular expressions can't be delimited by letters");
return;
}
/*
* undocumented vi feature:
* "\/sub/" and "\?sub?" use last used search pattern (almost like
* //sub/r). "\&sub&" use last substitute pattern (like //sub/).
*/
if (*cmd == '\\')
{
++cmd;
if (vim_strchr((char_u *)"/?&", *cmd) == NULL)
{
emsg(e_backslash);
return;
}
if (*cmd != '&')
which_pat = RE_SEARCH; /* use last '/' pattern */
pat = (char_u *)""; /* empty search pattern */
delimiter = *cmd++; /* remember delimiter character */
}
else /* find the end of the regexp */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -