📄 vi.c
字号:
doingdot = FALSE; } /* process the key as a command */ tcurs = cursor; force_flags = NO_FLAGS; switch (keyptr->args & ARGSMASK) { case ZERO: if (count == 0) { tcurs = cursor & ~(BLKSIZE - 1); break; } /* else fall through & treat like other digits... */ case DIGIT: count = count * 10 + key - '0'; break; case KEYWORD: /* if not on a keyword, fail */ pfetch(markline(cursor)); key = markidx(cursor); if (!isalnum(ptext[key])) { tcurs = MARK_UNSET; break; } /* find the start of the keyword */ while (key > 0 && isalnum(ptext[key - 1])) { key--; } tcurs = (cursor & ~(BLKSIZE - 1)) + key; /* copy it into a buffer, and NUL-terminate it */ i = 0; do { text[i++] = ptext[key++]; } while (isalnum(ptext[key])); text[i] = '\0'; /* call the function */ tcurs = (*keyptr->func)(text, tcurs, count); count = 0L; break; case NO_ARGS: if (keyptr->func) { (*keyptr->func)(); } else { beep(); } count = 0L; break; case CURSOR: tcurs = (*keyptr->func)(cursor, count, key, prevkey); count = 0L; break; case CURSOR_CNT_KEY: if (doingdot) { tcurs = (*keyptr->func)(cursor, count, dotkey2); } else { /* get a key */ i = getkey(KEYMODE(keyptr->args)); if (i == '\033') /* ESC */ { count = 0; tcurs = MARK_UNSET; break; /* exit from "case CURSOR_CNT_KEY" */ } else if (i == ctrl('V')) { i = getkey(0); } /* if part of an SDOT command, remember it */ if (keyptr->flags & SDOT || (prevkey && vikeys[prevkey].flags & SDOT)) { dotkey2 = i; } /* do it */ tcurs = (*keyptr->func)(cursor, count, i); } count = 0L; break; case CURSOR_MOVED:#ifndef NO_VISIBLE if (V_from) { range = cursor; tcurs = V_from; count = 0L; prevkey = key; key = (V_linemd ? 'V' : 'v'); keyptr = &vikeys[key]; } else#endif { prevkey = key; range = cursor; force_flags = LNMD|INCL; } break; case CURSOR_EOL: prevkey = key; /* a zero-length line needs special treatment */ pfetch(markline(cursor)); if (plen == 0) { /* act on a zero-length section of text */ range = tcurs = cursor; key = '0'; } else { /* act like CURSOR_MOVED with '$' movement */ range = cursor; tcurs = m_rear(cursor, 1L); key = '$'; } count = 0L; keyptr = &vikeys[key]; break; case CURSOR_TEXT: do { text[0] = key; if (vgets(key, text + 1, sizeof text - 1) >= 0) { /* reassure user that <CR> was hit */ qaddch('\r'); refresh(); /* call the function with the text */ tcurs = (*keyptr->func)(cursor, text); } else { if (exwrote || mode == MODE_COLON) { redraw(MARK_UNSET, FALSE); } mode = MODE_VI; } } while (mode == MODE_COLON); count = 0L; break; } /* if that command took us out of vi mode, then exit the loop * NOW, without tweaking the cursor or anything. This is very * important when mode == MODE_QUIT. */ if (mode != MODE_VI) { break; } /* now move the cursor, as appropriate */ if (keyptr->args == CURSOR_MOVED) { /* the < and > keys have FRNT, * but it shouldn't be applied yet */ tcurs = adjmove(cursor, tcurs, 0); } else { tcurs = adjmove(cursor, tcurs, (int)keyptr->flags | force_flags); } /* was that the end of a d/c/y/</>/! command? */ if (prevkey && ((keyptr->flags & MVMT)#ifndef NO_VISIBLE || V_from#endif ) && count == 0L) {#ifndef NO_VISIBLE /* turn off the hilight */ V_from = 0L;#endif /* if the movement command failed, cancel operation */ if (tcurs == MARK_UNSET) { prevkey = 0; count = 0; continue; } /* make sure range=front and tcurs=rear. Either way, * leave cursor=range since that's where we started. */ cursor = range; if (tcurs < range) { range = tcurs; tcurs = cursor; } /* The 'w' and 'W' destinations should never take us * to the front of a line. Instead, they should take * us only to the end of the preceding line. */ if ((keyptr->flags & (MVMT|NREL|LNMD|FRNT|INCL)) == MVMT && markline(range) < markline(tcurs) && (markline(tcurs) > nlines || tcurs == m_front(tcurs, 0L))) { tcurs = (tcurs & ~(BLKSIZE - 1)) - BLKSIZE; pfetch(markline(tcurs)); tcurs += plen; } /* adjust for line mode & inclusion of last char/line */ i = (keyptr->flags | vikeys[prevkey].flags); switch ((i | force_flags) & (INCL|LNMD)) { case INCL: tcurs++; break; case INCL|LNMD: tcurs += BLKSIZE; /* fall through... */ case LNMD: range &= ~(BLKSIZE - 1); tcurs &= ~(BLKSIZE - 1); break; } /* run the function */ tcurs = (*vikeys[prevkey].func)(range, tcurs); if (mode == MODE_VI) { (void)adjmove(cursor, cursor, 0); cursor = adjmove(cursor, tcurs, (int)vikeys[prevkey].flags); } /* cleanup */ prevkey = 0; } else if (!prevkey) { if (tcurs != MARK_UNSET) cursor = tcurs; } }}/* This function adjusts the MARK value that they return; here we make sure * it isn't past the end of the line, and that the column hasn't been * *accidentally* changed. */MARK adjmove(old, new, flags) MARK old; /* the cursor position before the command */ REG MARK new; /* the cursor position after the command */ int flags; /* various flags regarding cursor mvmt */{ static int colno; /* the column number that we want */ REG char *text; /* used to scan through the line's text */ REG int i;#ifdef DEBUG watch();#endif /* if the command failed, bag it! */ if (new == MARK_UNSET) { beep(); return old; } /* if this is a non-relative movement, set the '' mark */ if (flags & NREL) { mark[26] = old; } /* make sure it isn't past the end of the file */ if (markline(new) < 1) { new = MARK_FIRST; } else if (markline(new) > nlines) { new = MARK_LAST; } /* fetch the new line */ pfetch(markline(new)); /* move to the front, if we're supposed to */ if (flags & FRNT) { new = m_front(new, 1L); } /* change the column#, or change the mark to suit the column# */ if (!(flags & NCOL)) { /* change the column# */ i = markidx(new); if (i == BLKSIZE - 1) { new &= ~(BLKSIZE - 1); if (plen > 0) { new += plen - 1; } colno = BLKSIZE * 8; /* one heck of a big colno */ } else if (plen > 0) { if (i >= plen) { new = (new & ~(BLKSIZE - 1)) + plen - 1; } colno = idx2col(new, ptext, FALSE); } else { new &= ~(BLKSIZE - 1); colno = 0; } } else { /* adjust the mark to get as close as possible to column# */ for (i = 0, text = ptext; i <= colno && *text; text++) { if (*text == '\t' && !*o_list) { i += *o_tabstop - (i % *o_tabstop); } else if (UCHAR(*text) < ' ' || *text == 127) { i += 2; }#ifndef NO_CHARATTR else if (*o_charattr && text[0] == '\\' && text[1] == 'f' && text[2]) { text += 2; /* plus one more in "for()" stmt */ }#endif else { i++; } } if (text > ptext) { text--; } new = (new & ~(BLKSIZE - 1)) + (int)(text - ptext); } return new;}#ifdef DEBUGwatch(){ static wasset; if (*origname) { wasset = TRUE; } else if (wasset) { mode = MODE_EX; msg("origname was clobbered"); endwin(); abort(); } if (wasset && nlines == 0) { mode = MODE_EX; msg("nlines=0"); endwin(); abort(); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -