📄 cmd2.c
字号:
tmpblk.c[len++] = '\n'; tmpblk.c[len] = '\0'; /* make the change */ ChangeText { frommark &= ~(BLKSIZE - 1); tomark &= ~(BLKSIZE - 1); tomark += BLKSIZE; change(frommark, tomark, tmpblk.c); } /* Reporting... */ rptlines = markline(tomark) - markline(frommark) - 1L; rptlabel = "joined";}/*ARGSUSED*/void cmd_shift(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ long l; /* line number counter */ int oldidx; /* number of chars previously used for indent */ int newidx; /* number of chars in the new indent string */ int oldcol; /* previous indent amount */ int newcol; /* new indent amount */ char *text; /* pointer to the old line's text */ ChangeText { /* for each line to shift... */ for (l = markline(frommark); l <= markline(tomark); l++) { /* get the line - ignore empty lines unless ! mode */ text = fetchline(l); if (!*text && !bang) continue; /* calc oldidx and oldcol */ for (oldidx = 0, oldcol = 0; text[oldidx] == ' ' || text[oldidx] == '\t'; oldidx++) { if (text[oldidx] == ' ') { oldcol += 1; } else { oldcol += *o_tabstop - (oldcol % *o_tabstop); } } /* calc newcol */ if (cmd == CMD_SHIFTR) { newcol = oldcol + (*o_shiftwidth & 0xff); } else { newcol = oldcol - (*o_shiftwidth & 0xff); if (newcol < 0) newcol = 0; } /* if no change, then skip to next line */ if (oldcol == newcol) continue; /* build a new indent string */ newidx = 0; if (*o_autotab) { while (newcol >= *o_tabstop) { tmpblk.c[newidx++] = '\t'; newcol -= *o_tabstop; } } while (newcol > 0) { tmpblk.c[newidx++] = ' '; newcol--; } tmpblk.c[newidx] = '\0'; /* change the old indent string into the new */ change(MARK_AT_LINE(l), MARK_AT_LINE(l) + oldidx, tmpblk.c); } } /* Reporting... */ rptlines = markline(tomark) - markline(frommark) + 1L; if (cmd == CMD_SHIFTR) { rptlabel = ">ed"; } else { rptlabel = "<ed"; }}/*ARGSUSED*/void cmd_read(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ int fd, rc; /* used while reading from the file */ char *scan; /* used for finding NUL characters */ int hadnul; /* boolean: any NULs found? */ int addnl; /* boolean: forced to add newlines? */ int len; /* number of chars in current line */ long lines; /* number of lines in current block */ struct stat statb; /* special case: if ":r !cmd" then let the filter() function do it */ if (extra[0] == '!') { filter(frommark, MARK_UNSET, extra + 1, TRUE); return; } /* open the file */ fd = open(extra, O_RDONLY); if (fd < 0) { msg("Can't open \"%s\"", extra); return; }#ifndef CRUNCH if (stat(extra, &statb) < 0) { msg("Can't stat \"%s\"", extra); }# if TOS if (statb.st_mode & S_IJDIR)# else# if OSK if (statb.st_mode & S_IFDIR)# else if ((statb.st_mode & S_IFMT) != S_IFREG)# endif# endif { msg("\"%s\" is not a regular file", extra); return; }#endif /* not CRUNCH */ /* get blocks from the file, and add them */ ChangeText { /* insertion starts at the line following frommark */ tomark = frommark = (frommark | (BLKSIZE - 1L)) + 1L; len = 0; hadnul = addnl = FALSE; /* add an extra newline, so partial lines at the end of * the file don't trip us up */ add(tomark, "\n"); /* for each chunk of text... */ while ((rc = tread(fd, tmpblk.c, BLKSIZE - 1)) > 0) { /* count newlines, convert NULs, etc. ... */ for (lines = 0, scan = tmpblk.c; rc > 0; rc--, scan++) { /* break up long lines */ if (*scan != '\n' && len + 2 > BLKSIZE) { *scan = '\n'; addnl = TRUE; } /* protect against NUL chars in file */ if (!*scan) { *scan = 0x80; hadnul = TRUE; } /* starting a new line? */ if (*scan == '\n') { /* reset length at newline */ len = 0; lines++; } else { len++; } } /* add the text */ *scan = '\0'; add(tomark, tmpblk.c); tomark += MARK_AT_LINE(lines) + len - markidx(tomark); } /* if partial last line, then retain that first newline */ if (len > 0) { msg("Last line had no newline"); tomark += BLKSIZE; /* <- for the rptlines calc */ } else /* delete that first newline */ { delete(tomark, (tomark | (BLKSIZE - 1L)) + 1L); } } /* close the file */ close(fd); /* Reporting... */ rptlines = markline(tomark) - markline(frommark); rptlabel = "read"; if (mode == MODE_EX) { cursor = (tomark & ~BLKSIZE) - BLKSIZE; } else { cursor = frommark; } if (addnl) msg("Newlines were added to break up long lines"); if (hadnul) msg("NULs were converted to 0x80");}/*ARGSUSED*/void cmd_undo(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ undo();}/* print the selected lines *//*ARGSUSED*/void cmd_print(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ REG char *scan; REG long l; REG int col; for (l = markline(frommark); l <= markline(tomark); l++) { /* display a line number, if CMD_NUMBER */ if (cmd == CMD_NUMBER) { sprintf(tmpblk.c, "%6ld ", l); qaddstr(tmpblk.c); col = 8; } else { col = 0; } /* get the next line & display it */ for (scan = fetchline(l); *scan; scan++) { /* expand tabs to the proper width */ if (*scan == '\t' && cmd != CMD_LIST) { do { qaddch(' '); col++; } while (col % *o_tabstop != 0); } else if (*scan > 0 && *scan < ' ' || *scan == '\177') { qaddch('^'); qaddch(*scan ^ 0x40); col += 2; } else if ((*scan & 0x80) && cmd == CMD_LIST) { sprintf(tmpblk.c, "\\%03o", UCHAR(*scan)); qaddstr(tmpblk.c); col += 4; } else { qaddch(*scan); col++; } /* wrap at the edge of the screen */ if (!has_AM && col >= COLS) { addch('\n'); col -= COLS; } } if (cmd == CMD_LIST) { qaddch('$'); } addch('\n'); exrefresh(); }}/* move or copy selected lines *//*ARGSUSED*/void cmd_move(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ MARK destmark; /* parse the destination linespec. No defaults. Line 0 is okay */ destmark = cursor; if (!strcmp(extra, "0")) { destmark = 0L; } else if (linespec(extra, &destmark) == extra || !destmark) { msg("invalid destination address"); return; } /* flesh the marks out to encompass whole lines */ frommark &= ~(BLKSIZE - 1); tomark = (tomark & ~(BLKSIZE - 1)) + BLKSIZE; destmark = (destmark & ~(BLKSIZE - 1)) + BLKSIZE; /* make sure the destination is valid */ if (cmd == CMD_MOVE && destmark >= frommark && destmark < tomark) { msg("invalid destination address"); } /* Do it */ ChangeText { /* save the text to a cut buffer */ cutname('\0'); cut(frommark, tomark); /* if we're not copying, delete the old text & adjust destmark */ if (cmd != CMD_COPY) { delete(frommark, tomark); if (destmark >= frommark) { destmark -= (tomark - frommark); } } /* add the new text */ paste(destmark, FALSE, FALSE); } /* move the cursor to the last line of the moved text */ cursor = destmark + (tomark - frommark) - BLKSIZE; if (cursor < MARK_FIRST || cursor >= MARK_LAST + BLKSIZE) { cursor = MARK_LAST; } /* Reporting... */ rptlabel = ( (cmd == CMD_COPY) ? "copied" : "moved" );}/* execute EX commands from a file *//*ARGSUSED*/void cmd_source(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ /* must have a filename */ if (!*extra) { msg("\"source\" requires a filename"); return; } doexrc(extra);}#ifndef NO_AT/*ARGSUSED*/void cmd_at(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ static nest = FALSE; int result; char buf[MAXRCLEN]; /* don't allow nested macros */ if (nest) { msg("@ macros can't be nested"); return; } nest = TRUE; /* require a buffer name */ if (*extra == '"') extra++; if (!*extra || !isascii(*extra) ||!islower(*extra)) { msg("@ requires a cut buffer name (a-z)"); } /* get the contents of the buffer */ result = cb2str(*extra, buf, (unsigned)(sizeof buf)); if (result <= 0) { msg("buffer \"%c is empty", *extra); } else if (result >= sizeof buf) { msg("buffer \"%c is too large to execute", *extra); } else { /* execute the contents of the buffer as ex commands */ exstring(buf, result, '\\'); } nest = FALSE;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -