📄 vi.c
字号:
es->cursor = cur; } else return -1; } else { /* Don't save state in middle of macro.. */ if (is_undoable(*cmd) && !macro.p) { undo->winleft = es->winleft; memmove(undo->cbuf, es->cbuf, es->linelen); undo->linelen = es->linelen; undo->cursor = es->cursor; lastac = argcnt; memmove(lastcmd, cmd, MAXVICMD); } switch (*cmd) { case Ctrl('l'): case Ctrl('r'): redraw_line(1); break; case '@': { static char alias[] = "_\0"; struct tbl *ap; int olen, nlen; char *p, *nbuf; /* lookup letter in alias list... */ alias[1] = cmd[1]; ap = tsearch(&aliases, alias, hash(alias)); if (!cmd[1] || !ap || !(ap->flag & ISSET)) return -1; /* check if this is a recursive call... */ if ((p = (char *) macro.p)) while ((p = strchr(p, '\0')) && p[1]) if (*++p == cmd[1]) return -1; /* insert alias into macro buffer */ nlen = strlen(ap->val.s) + 1; olen = !macro.p ? 2 : macro.len - (macro.p - macro.buf); nbuf = alloc(nlen + 1 + olen, APERM); memcpy(nbuf, ap->val.s, nlen); nbuf[nlen++] = cmd[1]; if (macro.p) { memcpy(nbuf + nlen, macro.p, olen); afree(macro.buf, APERM); nlen += olen; } else { nbuf[nlen++] = '\0'; nbuf[nlen++] = '\0'; } macro.p = macro.buf = (unsigned char *) nbuf; macro.len = nlen; } break; case 'a': modified = 1; hnum = hlast; if (es->linelen != 0) es->cursor++; insert = INSERT; break; case 'A': modified = 1; hnum = hlast; del_range(0, 0); es->cursor = es->linelen; insert = INSERT; break; case 'S': es->cursor = domove(1, "^", 1); del_range(es->cursor, es->linelen); modified = 1; hnum = hlast; insert = INSERT; break; case 'Y': cmd = "y$"; /* ahhhhhh... */ case 'c': case 'd': case 'y': if (*cmd == cmd[1]) { c1 = *cmd == 'c' ? domove(1, "^", 1) : 0; c2 = es->linelen; } else if (!is_move(cmd[1])) return -1; else { if ((ncursor = domove(argcnt, &cmd[1], 1)) < 0) return -1; if (*cmd == 'c' && (cmd[1]=='w' || cmd[1]=='W') && !isspace(es->cbuf[es->cursor])) { while (isspace(es->cbuf[--ncursor])) ; ncursor++; } if (ncursor > es->cursor) { c1 = es->cursor; c2 = ncursor; } else { c1 = ncursor; c2 = es->cursor; if (cmd[1] == '%') c2++; } } if (*cmd != 'c' && c1 != c2) yank_range(c1, c2); if (*cmd != 'y') { del_range(c1, c2); es->cursor = c1; } if (*cmd == 'c') { modified = 1; hnum = hlast; insert = INSERT; } break; case 'p': modified = 1; hnum = hlast; if (es->linelen != 0) es->cursor++; while (putbuf(ybuf, yanklen, 0) == 0 && --argcnt > 0) ; if (es->cursor != 0) es->cursor--; if (argcnt != 0) return -1; break; case 'P': modified = 1; hnum = hlast; any = 0; while (putbuf(ybuf, yanklen, 0) == 0 && --argcnt > 0) any = 1; if (any && es->cursor != 0) es->cursor--; if (argcnt != 0) return -1; break; case 'C': modified = 1; hnum = hlast; del_range(es->cursor, es->linelen); insert = INSERT; break; case 'D': yank_range(es->cursor, es->linelen); del_range(es->cursor, es->linelen); if (es->cursor != 0) es->cursor--; break; case 'g': if (!argcnt) argcnt = hlast + 1; /* fall through */ case 'G': if (!argcnt) argcnt = 1; else argcnt = hlast - (source->line - argcnt); if (grabhist(modified, argcnt - 1) < 0) return -1; else { modified = 0; hnum = argcnt - 1; } break; case 'i': modified = 1; hnum = hlast; insert = INSERT; break; case 'I': modified = 1; hnum = hlast; es->cursor = domove(1, "^", 1); insert = INSERT; break; case 'j': case '+': case Ctrl('n'): if (grabhist(modified, hnum + argcnt) < 0) return -1; else { modified = 0; hnum += argcnt; } break; case 'k': case '-': case Ctrl('p'): if (grabhist(modified, hnum - argcnt) < 0) return -1; else { modified = 0; hnum -= argcnt; } break; case 'r': if (es->linelen == 0) return -1; modified = 1; hnum = hlast; if (cmd[1] == 0) vi_error(); else es->cbuf[es->cursor] = cmd[1]; break; case 'R': modified = 1; hnum = hlast; insert = REPLACE; break; case 's': if (es->linelen == 0) return -1; modified = 1; hnum = hlast; if (es->cursor + argcnt > es->linelen) argcnt = es->linelen - es->cursor; del_range(es->cursor, es->cursor + argcnt); insert = INSERT; break; case 'v': if (es->linelen == 0) return -1; if (!argcnt) { if (modified) { es->cbuf[es->linelen] = '\0'; source->line++; histsave(source->line, es->cbuf, 1); } else argcnt = source->line + 1 - (hlast - hnum); } shf_snprintf(es->cbuf, es->cbufsize, argcnt ? "%s %d" : "%s", "fc -e ${VISUAL:-${EDITOR:-vi}} --", argcnt); es->linelen = strlen(es->cbuf); return 2; case 'x': if (es->linelen == 0) return -1; modified = 1; hnum = hlast; if (es->cursor + argcnt > es->linelen) argcnt = es->linelen - es->cursor; yank_range(es->cursor, es->cursor + argcnt); del_range(es->cursor, es->cursor + argcnt); break; case 'X': if (es->cursor > 0) { modified = 1; hnum = hlast; if (es->cursor < argcnt) argcnt = es->cursor; yank_range(es->cursor - argcnt, es->cursor); del_range(es->cursor - argcnt, es->cursor); es->cursor -= argcnt; } else return -1; break; case 'u': t = es; es = undo; undo = t; break; case 'U': if (!modified) return -1; if (grabhist(modified, ohnum) < 0) return -1; modified = 0; hnum = ohnum; break; case '?': if (hnum == hlast) hnum = -1; /* ahhh */ case '/': c3 = 1; srchlen = 0; lastsearch = *cmd; /* fall through */ case 'n': case 'N': if (lastsearch == ' ') return -1; if (lastsearch == '?') c1 = 1; else c1 = 0; if (*cmd == 'N') c1 = !c1; if ((c2 = grabsearch(modified, hnum, c1, srchpat)) < 0) { if (c3) { restore_cbuf(); refresh(0); } return -1; } else { modified = 0; hnum = c2; ohnum = hnum; } break; case '_': { int inspace; char *p, *sp; if (histnum(-1) < 0) return -1; p = *histpos();#define issp(c) (isspace((c)) || (c) == '\n') if (argcnt) { while (*p && issp(*p)) p++; while (*p && --argcnt) { while (*p && !issp(*p)) p++; while (*p && issp(*p)) p++; } if (!*p) return -1; sp = p; } else { sp = p; inspace = 0; while (*p) { if (issp(*p)) inspace = 1; else if (inspace) { inspace = 0; sp = p; } p++; } p = sp; } modified = 1; hnum = hlast; if (es->cursor != es->linelen) es->cursor++; while (*p && !issp(*p)) { argcnt++; p++; } if (putbuf(space, 1, 0) != 0) argcnt = -1; else if (putbuf(sp, argcnt, 0) != 0) argcnt = -1; if (argcnt < 0) { if (es->cursor != 0) es->cursor--; return -1; } insert = INSERT; } break; case '~': { char *p; int i; if (es->linelen == 0) return -1; for (i = 0; i < argcnt; i++) { p = &es->cbuf[es->cursor]; if (islower(*p)) { modified = 1; hnum = hlast; *p = toupper(*p); } else if (isupper(*p)) { modified = 1; hnum = hlast; *p = tolower(*p); } if (es->cursor < es->linelen - 1) es->cursor++; } break; } case '#': { int ret = x_do_comment(es->cbuf, es->cbufsize, &es->linelen); if (ret >= 0) es->cursor = 0; return ret; } case '=': /* at&t ksh */ case Ctrl('e'): /* Nonstandard vi/ksh */ print_expansions(es, 1); break; case Ctrl('i'): /* Nonstandard vi/ksh */ if (!Flag(FVITABCOMPLETE)) return -1; complete_word(1, argcnt); break; case Ctrl('['): /* some annoying at&t ksh's */ if (!Flag(FVIESCCOMPLETE)) return -1; case '\\': /* at&t ksh */ case Ctrl('f'): /* Nonstandard vi/ksh */ complete_word(1, argcnt); break; case '*': /* at&t ksh */ case Ctrl('x'): /* Nonstandard vi/ksh */ expand_word(1); break; } if (insert == 0 && es->cursor != 0 && es->cursor >= es->linelen) es->cursor--; } return 0;}static intdomove(argcnt, cmd, sub) int argcnt; const char *cmd; int sub;{ int bcount, UNINITIALIZED(i), t; int UNINITIALIZED(ncursor); switch (*cmd) { case 'b': if (!sub && es->cursor == 0) return -1; ncursor = backword(argcnt); break; case 'B': if (!sub && es->cursor == 0) return -1; ncursor = Backword(argcnt); break; case 'e': if (!sub && es->cursor + 1 >= es->linelen) return -1; ncursor = endword(argcnt); if (sub && ncursor < es->linelen) ncursor++; break; case 'E': if (!sub && es->cursor + 1 >= es->linelen) return -1; ncursor = Endword(argcnt); if (sub && ncursor < es->linelen) ncursor++; break; case 'f': case 'F': case 't': case 'T': fsavecmd = *cmd; fsavech = cmd[1]; /* drop through */ case ',': case ';': if (fsavecmd == ' ') return -1; i = fsavecmd == 'f' || fsavecmd == 'F'; t = fsavecmd > 'a'; if (*cmd == ',') t = !t; if ((ncursor = findch(fsavech, argcnt, t, i)) < 0) return -1; if (sub && t) ncursor++; break; case 'h': case Ctrl('h'): if (!sub && es->cursor == 0) return -1; ncursor = es->cursor - argcnt; if (ncursor < 0) ncursor = 0; break; case ' ': case 'l': if (!sub && es->cursor + 1 >= es->linelen) return -1; if (es->linelen != 0) { ncursor = es->cursor + argcnt; if (ncursor > es->linelen) ncursor = es->linelen; } break; case 'w': if (!sub && es->cursor + 1 >= es->linelen) return -1; ncursor = forwword(argcnt); break; case 'W': if (!sub && es->cursor + 1 >= es->linelen) return -1; ncursor = Forwword(argcnt); break; case '0': ncursor = 0; break; case '^': ncursor = 0; while (ncursor < es->linelen - 1 && isspace(es->cbuf[ncursor])) ncursor++; break; case '|': ncursor = argcnt; if (ncursor > es->linelen) ncursor = es->linelen; if (ncursor) ncursor--; break; case '$': if (es->linelen != 0) ncursor = es->linelen; else ncursor = 0; break; case '%': ncursor = es->cursor; while (ncursor < es->linelen && (i = bracktype(es->cbuf[ncursor])) == 0) ncursor++; if (ncursor == es->linelen) return -1; bcount = 1; do { if (i > 0) { if (++ncursor >= es->linelen) return -1; } else { if (--ncursor < 0) return -1; } t = bracktype(es->cbuf[ncursor]); if (t == i) bcount++; else if (t == -i) bcount--; } while (bcount != 0); if (sub && i > 0) ncursor++; break; default: return -1; } return ncursor;}static intredo_insert(count) int count;{ while (count-- > 0) if (putbuf(ibuf, inslen, insert==REPLACE) != 0) return -1; if (es->cursor > 0) es->cursor--; insert = 0; return 0;}static voidyank_range(a, b) int a, b;{ yanklen = b - a; if (yanklen != 0) memmove(ybuf, &es->cbuf[a], yanklen);}static intbracktype(ch) int ch;{ switch (ch) { case '(': return 1; case '[': return 2; case '{': return 3; case ')': return -1; case ']': return -2; case '}': return -3; default: return 0; }}/* * Non user interface editor routines below here */static int cur_col; /* current column on line */static int pwidth; /* width of prompt */static int prompt_trunc; /* how much of prompt to truncate */static int prompt_skip; /* how much of prompt to skip */static int winwidth; /* width of window */static char *wbuf[2]; /* window buffers */static int wbuf_len; /* length of window buffers (x_cols-3)*/static int win; /* window buffer in use */static char morec; /* more character at right of window */static int lastref; /* argument to last refresh() */static char holdbuf[CMDLEN]; /* place to hold last edit buffer */static int holdlen; /* length of holdbuf */static voidsave_cbuf(){ memmove(holdbuf, es->cbuf, es->linelen); holdlen = es->linelen; holdbuf[holdlen] = '\0';}static voidrestore_cbuf(){ es->cursor = 0; es->linelen = holdlen; memmove(es->cbuf, holdbuf, holdlen);}/* return a new edstate */static struct edstate *save_edstate(old) struct edstate *old;{ struct edstate *new; new = (struct edstate *)alloc(sizeof(struct edstate), APERM); new->cbuf = alloc(old->cbufsize, APERM); new->cbufsize = old->cbufsize; strcpy(new->cbuf, old->cbuf); new->linelen = old->linelen; new->cursor = old->cursor; new->winleft = old->winleft; return new;}static voidrestore_edstate(new, old) struct edstate *old, *new;{ strncpy(new->cbuf, old->cbuf, old->linelen); new->linelen = old->linelen; new->cursor = old->cursor; new->winleft = old->winleft; free_edstate(old);}static voidfree_edstate(old) struct edstate *old;{ afree(old->cbuf, APERM); afree((char *)old, APERM);}static voidedit_reset(buf, len) char *buf; size_t len;{ const char *p; es = &ebuf; es->cbuf = buf; es->cbufsize = len; undo = &undobuf; undo->cbufsize = len; es->linelen = undo->linelen = 0; es->cursor = undo->cursor = 0; es->winleft = undo->winleft = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -