📄 cmd1.c
字号:
/* also called from :wq -- always writes back in this case *//*ARGSUSED*/void cmd_xit(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ static long whenwarned; /* when the user was last warned of extra files */ int oldflag; /* if there are more files to edit, then warn user */ if (argno >= 0 && argno + 1 < nargs && whenwarned != changes && (!bang || cmd != CMD_QUIT)) { msg("More files to edit -- Use \":n\" to go to next file"); whenwarned = changes; return; } if (cmd == CMD_QUIT) { oldflag = *o_autowrite; *o_autowrite = FALSE; if (tmpabort(bang)) { mode = MODE_QUIT; } else { msg("Use q! to abort changes, or wq to save changes"); } *o_autowrite = oldflag; } else { /* else try to save this file */ oldflag = tstflag(file, MODIFIED); if (cmd == CMD_WQUIT) setflag(file, MODIFIED); if (tmpend(bang)) { mode = MODE_QUIT; } else { msg("Could not save file -- use quit! to abort changes, or w filename"); } if (!oldflag) clrflag(file, MODIFIED); }}/*ARGSUSED*/void cmd_args(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ char *scan; int col; int arg; int scrolled = FALSE; int width; /* if no extra names given, or just current name, then report the args * we have now. */ if (!extra || !*extra) { /* empty args list? */ if (nargs == 1 && !*args) { return; } /* list the arguments */ for (scan = args, col = arg = 0; arg < nargs; scan += width + 1, col += width, arg++) { width = strlen(scan); if (col + width >= COLS - 4) { addch('\n'); col = 0; scrolled = TRUE; } else if (col > 0) { addch(' '); col++; } if (arg == argno) { addch('['); addstr(scan); addch(']'); col += 2; } else { addstr(scan); } } /* write a trailing newline */ if ((mode == MODE_EX || mode == MODE_COLON || scrolled) && col) { addch('\n'); } exrefresh(); } else /* new args list given */ { for (scan = args, nargs = 1; *extra; ) { if (isspace(*extra)) { *scan++ = '\0'; while (isspace(*extra)) { extra++; } if (*extra) { nargs++; } } else { *scan++ = *extra++; } } *scan = '\0'; /* reset argno to before the first, so :next will go to first */ argno = -1; if (nargs != 1) { msg("%d files to edit", nargs); } }}/*ARGSUSED*/void cmd_cd(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ char *getenv();#ifndef CRUNCH /* if current file is modified, and no '!' was given, then error */ if (tstflag(file, MODIFIED) && !bang) { msg("File modified; use \"cd! %s\" to switch anyway", extra); }#endif /* default directory name is $HOME */ if (!*extra) { extra = getenv("HOME"); if (!extra) { msg("environment variable $HOME not set"); return; } } /* go to the directory */ if (chdir(extra) < 0) { perror(extra); }}/*ARGSUSED*/void cmd_map(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ char *mapto; char *build, *scan;#ifndef NO_FKEY static char *fnames[NFKEYS] = { "#10", "#1", "#2", "#3", "#4", "#5", "#6", "#7", "#8", "#9",# ifndef NO_SHIFT_FKEY "#10s", "#1s", "#2s", "#3s", "#4s", "#5s", "#6s", "#7s", "#8s", "#9s",# ifndef NO_CTRL_FKEY "#10c", "#1c", "#2c", "#3c", "#4c", "#5c", "#6c", "#7c", "#8c", "#9c",# ifndef NO_ALT_FKEY "#10a", "#1a", "#2a", "#3a", "#4a", "#5a", "#6a", "#7a", "#8a", "#9a",# endif# endif# endif }; int key;#endif /* "map" with no extra will dump the map table contents */ if (!*extra) {#ifndef NO_ABBR if (cmd == CMD_ABBR) { dumpkey(bang ? WHEN_EX|WHEN_VIINP|WHEN_VIREP : WHEN_VIINP|WHEN_VIREP, TRUE); } else#endif { dumpkey(bang ? WHEN_VIINP|WHEN_VIREP : WHEN_VICMD, FALSE); } } else { /* "extra" is key to map, followed by what it maps to */ /* handle quoting inside the "raw" string */ for (build = mapto = extra; *mapto && (*mapto != ' ' && *mapto != '\t'); *build++ = *mapto++) { if (*mapto == ctrl('V') && mapto[1]) { mapto++; } } /* skip whitespace, and mark the end of the "raw" string */ while ((*mapto == ' ' || *mapto == '\t')) { *mapto++ = '\0'; } *build = '\0'; /* strip ^Vs from the "cooked" string */ for (scan = build = mapto; *scan; *build++ = *scan++) { if (*scan == ctrl('V') && scan[1]) { scan++; } } *build = '\0';#ifndef NO_FKEY /* if the mapped string is '#' and a number, then assume * the user wanted that function key */ if (extra[0] == '#' && isdigit(extra[1])) { key = atoi(extra + 1) % 10;# ifndef NO_SHIFT_FKEY build = extra + strlen(extra) - 1; if (*build == 's') key += 10;# ifndef NO_CTRL_FKEY else if (*build == 'c') key += 20;# ifndef NO_ALT_FKEY else if (*build == 'a') key += 30;# endif# endif# endif if (FKEY[key]) mapkey(FKEY[key], mapto, bang ? WHEN_VIINP|WHEN_VIREP : WHEN_VICMD, fnames[key]); else msg("This terminal has no %s key", fnames[key]); } else#endif#ifndef NO_ABBR if (cmd == CMD_ABBR || cmd == CMD_UNABBR) { mapkey(extra, mapto, bang ? WHEN_EX|WHEN_VIINP|WHEN_VIREP : WHEN_VIINP|WHEN_VIREP, "abbr"); } else#endif { mapkey(extra, mapto, bang ? WHEN_VIINP|WHEN_VIREP : WHEN_VICMD, (char *)0); } }}/*ARGSUSED*/void cmd_set(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ if (!*extra) { dumpopts(FALSE);/* "FALSE" means "don't dump all" - only set */ } else if (!strcmp(extra, "all")) { dumpopts(TRUE); /* "TRUE" means "dump all" - even unset vars */ } else { setopts(extra); /* That option may have affected the appearence of text */ changes++; }}/*ARGSUSED*/void cmd_tag(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ int fd; /* file descriptor used to read the file */ char *scan; /* used to scan through the tmpblk.c */#ifdef INTERNAL_TAGS char *cmp; /* char of tag name we're comparing, or NULL */ char *end; /* marks the end of chars in tmpblk.c */#else int i;#endif#ifndef NO_MAGIC char wasmagic; /* preserves the original state of o_magic */#endif static char prevtag[30]; /* if no tag is given, use the previous tag */ if (!extra || !*extra) { if (!*prevtag) { msg("No previous tag"); return; } extra = prevtag; } else { strncpy(prevtag, extra, sizeof prevtag); prevtag[sizeof prevtag - 1] = '\0'; }#ifndef INTERNAL_TAGS /* use "ref" to look up the tag info for this tag */ sprintf(tmpblk.c, "ref -t %s%s %s", (*origname ? "-f" : ""),origname, prevtag); fd = rpipe(tmpblk.c, 0); if (fd < 0) { msg("Can't run \"%s\"", tmpblk.c); return; } /* try to read the tag info */ for (scan = tmpblk.c; (i = tread(fd, scan, scan - tmpblk.c + BLKSIZE)) > 0; scan += i) { } *scan = '\0'; /* close the pipe. abort if error */ if (rpclose(fd) != 0 || scan < tmpblk.c + 3) { msg("tag \"%s\" not found", extra); return; }#else /* use internal code to look up the tag */ /* open the tags file */ fd = open(TAGS, O_RDONLY); if (fd < 0) { msg("No tags file"); return; } /* Hmmm... this would have been a lot easier with <stdio.h> */ /* find the line with our tag in it */ for(scan = end = tmpblk.c, cmp = extra; ; scan++) { /* read a block, if necessary */ if (scan >= end) { end = tmpblk.c + tread(fd, tmpblk.c, BLKSIZE); scan = tmpblk.c; if (scan >= end) { msg("tag \"%s\" not found", extra); close(fd); return; } } /* if we're comparing, compare... */ if (cmp) { /* matched??? wow! */ if (!*cmp && *scan == '\t') { break; } if (*cmp++ != *scan) { /* failed! skip to newline */ cmp = (char *)0; } } /* if we're skipping to newline, do it fast! */ if (!cmp) { while (scan < end && *scan != '\n') { scan++; } if (scan < end) { cmp = extra; } } } /* found it! get the rest of the line into memory */ for (cmp = tmpblk.c, scan++; scan < end && *scan != '\n'; ) { *cmp++ = *scan++; } if (scan == end) { tread(fd, cmp, BLKSIZE - (int)(cmp - tmpblk.c)); } else *cmp = *scan; /* we can close the tags file now */ close(fd);#endif /* INTERNAL_TAGS */ /* extract the filename from the line, and edit the file */ for (scan = tmpblk.c; *scan != '\t'; scan++) { } *scan++ = '\0'; if (strcmp(origname, tmpblk.c) != 0) { if (!tmpabort(bang)) { msg("Use :tag! to abort changes, or :w to save changes"); return; } tmpstart(tmpblk.c); } /* move to the desired line (or to line 1 if that fails) */#ifndef NO_MAGIC wasmagic = *o_magic; *o_magic = FALSE;#endif cursor = MARK_FIRST; linespec(scan, &cursor); if (cursor == MARK_UNSET) { cursor = MARK_FIRST; msg("Tag's address is out of date"); }#ifndef NO_MAGIC *o_magic = wasmagic;#endif}/* describe this version of the program *//*ARGSUSED*/void cmd_version(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ msg("%s", VERSION);#ifdef CREDIT msg("%s", CREDIT);#endif#ifdef CREDIT2 msg("%s", CREDIT2);#endif#ifdef COMPILED_BY msg("Compiled by %s", COMPILED_BY);#endif#ifdef COPYING msg("%s", COPYING);#endif}#ifndef NO_MKEXRC/* make a .exrc file which describes the current configuration *//*ARGSUSED*/void cmd_mkexrc(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ int fd; /* the default name for the .exrc file EXRC */ if (!*extra) { extra = EXRC; } /* create the .exrc file */ fd = creat(extra, FILEPERMS); if (fd < 0) { msg("Couldn't create a new \"%s\" file", extra); return; } /* save stuff */ saveopts(fd); savemaps(fd, FALSE);#ifndef NO_ABBR savemaps(fd, TRUE);#endif#ifndef NO_DIGRAPH savedigs(fd);#endif#ifndef NO_COLOR savecolor(fd);#endif /* close the file */ close(fd); msg("Configuration saved");}#endif#ifndef NO_DIGRAPH/*ARGSUSED*/void cmd_digraph(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ do_digraph(bang, extra);}#endif#ifndef NO_ERRLIST static char errfile[256]; /* the name of a file containing an error */static long errline; /* the line number for an error */static int errfd = -2; /* fd of the errlist file *//* This static function tries to parse an error message. * * For most compilers, the first word is taken to be the name of the erroneous * file, and the first number after that is taken to be the line number where * the error was detected. The description of the error follows, possibly * preceded by an "error ... :" or "warning ... :" label which is skipped. * * For Coherent, error messages look like "line#: filename: message".
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -