/* * Save the contents of the current * buffer in its associatd file. No nothing * if nothing has changed (this may be a bug, not a * feature). Error if there is no remembered file * name for the buffer. Bound to "C-X C-S". May * get called by "C-Z". */ int filesave(int f, int n) { struct window *wp; int s; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes. */ return TRUE; if (curbp->b_fname[0] == 0) { /* Must have a name. */ mlwrite("No file name"); return FALSE; } /* complain about truncated files */ if ((curbp->b_flag & BFTRUNC) != 0) { if (mlyesno("Truncated file ... write it out") == FALSE) { mlwrite("(Aborted)"); return FALSE; } } if ((s = writeout(curbp->b_fname)) == TRUE) { curbp->b_flag &= ~BFCHG; wp = wheadp; /* Update mode lines. */ while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; wp = wp->w_wndp; } } return s; }
/* * lock: * Check and lock a file from access by others * returns TRUE = files was not locked and now is * FALSE = file was locked and overridden * ABORT = file was locked, abort command * * char *fname; file name to lock */ int lock(char *fname) { char *locker; /* lock error message */ int status; /* return status */ char msg[NSTRING]; /* message string */ /* attempt to lock the file */ locker = dolock(fname); if (locker == NULL) /* we win */ return TRUE; /* file failed...abort */ if (strncmp(locker, "LOCK", 4) == 0) { lckerror(locker); return ABORT; } /* someone else has it....override? */ xstrcpy(msg, "File in use by "); strcat(msg, locker); strcat(msg, ", override?"); status = mlyesno(msg); /* ask them */ if (status == TRUE) return FALSE; else return ABORT; }
/* * Asks the user if they wish to continue macro execution. * does nothing when recording, must meSTOP the macro execution so * mlyesno goes to the keyboard. */ int macroQuery(int f, int n) { if(kbdmode == mePLAY) { int rr ; /* force a screen update */ update(true); kbdmode = meSTOP ; if((rr = mlyesno((meUByte *)"Continue macro")) == meABORT) return meABORT ; if(rr == false) { kbdrep-- ; kbdoff = 0 ; } if(kbdrep) kbdmode = mePLAY ; else return false ; } else if(kbdmode != meRECORD) return mlwrite(MWABORT,(meUByte *)"Not defining macro") ; return true ; }
/* Note the return value for this is: * meABORT - there was a major failure (i.e. couldn't open the file) * meFALSE - user quit * meTRUE - succeded * this is used by the exit function which ignore the major failures */ static int regTestSave(meRegNode *sroot, int flags) { /* if its not a file or not changed or the changes are to be discarded * then nothing to do */ if(!(sroot->mode & meREGMODE_FROOT) || !(sroot->mode & meREGMODE_CHANGE) || (sroot->mode & meREGMODE_DISCARD)) return meTRUE ; if((flags & 0x01) && !(sroot->mode & meREGMODE_AUTO)) { meUByte prompt[meBUF_SIZE_MAX] ; int ret ; meStrcpy(prompt,(sroot->value != NULL) ? sroot->value:sroot->name) ; meStrcat(prompt,": Save registry") ; if((ret = mlyesno(prompt)) == meABORT) { ctrlg(meFALSE,1) ; return meFALSE ; } if(ret == meFALSE) return meTRUE ; } return regSave(sroot,NULL,sroot->mode) ; }
/* ARGSUSED */ int vl_setkey(int f GCC_UNUSED, int n GCC_UNUSED) { char result[NKEYLEN]; int rc = get_encryption_key(result, sizeof(result)); if (rc == TRUE) { TRACE(("set key for %s\n", curbp->b_bname)); (void) vl_strncpy(curbp->b_cryptkey, result, sizeof(curbp->b_cryptkey)); make_local_b_val(curbp, MDCRYPT); set_b_val(curbp, MDCRYPT, TRUE); curwp->w_flag |= WFMODE; } else if (rc == FALSE) { if (curbp->b_cryptkey[0] != EOS) { rc = mlyesno("Discard encryption key"); if (rc == TRUE) { TRACE(("reset key for %s\n", curbp->b_bname)); curbp->b_cryptkey[0] = EOS; if (global_b_val(MDCRYPT)) { make_local_b_val(curbp, MDCRYPT); set_b_val(curbp, MDCRYPT, FALSE); curwp->w_flag |= WFMODE; } else if (b_val(curbp, MDCRYPT)) { make_global_val(curbp->b_values.bv, global_b_values.bv, MDCRYPT); curwp->w_flag |= WFMODE; } } } } return (rc); }
/* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int quit (int f, int n) { int s; if (f != FALSE /* Argument forces it */ || anycb () == FALSE /* All buffers clean */ || (s = mlyesno ("Modified buffers exist. Leave anyway")) == TRUE) { vttidy (); exit (0); } mlwrite (""); return (s); }
/* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ globle int edquit( void *theEnv, int f, int n) { register int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ || (s=mlyesno(theEnv,"Modified Buffers! Quit")) == TRUE) { vttidy(); full_cleanup(theEnv); return(EXIT); } return (s); }
/* * This routine blows away all of the text in a buffer. If the buffer is * marked as changed then we ask if it is ok to blow it away; this is to save * the user the grief of losing text. The window chain is nearly always wrong * if this gets called; the caller must arrange for the updates that are * required. Return TRUE if everything looks good. */ int bclear (BUFFER *bp) { LINE *lp; int s; if ((bp->b_flag & BFTEMP) == 0 /* Not scratch buffer */ && (bp->b_flag & BFCHG) != 0 /* Something changed */ && (s = mlyesno ("Discard changes")) != TRUE) return (s); bp->b_flag &= ~BFCHG; /* Not changed */ while ((lp = lforw (bp->b_linep)) != bp->b_linep) lfree (lp); bp->b_dotp = bp->b_linep; /* Fix "." */ bp->b_doto = 0; bp->b_markp = 0; /* Invalidate "mark" */ bp->b_marko = 0; return (TRUE); }
/* * This routine blows away all of the text * in a buffer. If the buffer is marked as changed * then we ask if it is ok to blow it away; this is * to save the user the grief of losing text. The * window chain is nearly always wrong if this gets * called; the caller must arrange for the updates * that are required. Return TRUE if everything * looks good. */ int bclear(struct buffer *bp) { struct line *lp; int s; if ((bp->b_flag & BFINVS) == 0 /* Not scratch buffer. */ && (bp->b_flag & BFCHG) != 0 /* Something changed */ && (s = mlyesno("Discard changes")) != TRUE) return s; bp->b_flag &= ~BFCHG; /* Not changed */ while ((lp = lforw(bp->b_linep)) != bp->b_linep) lfree(lp); bp->b_dotp = bp->b_linep; /* Fix "." */ bp->b_doto = 0; bp->b_markp = NULL; /* Invalidate "mark" */ bp->b_marko = 0; return TRUE; }
/* * Set the buffer's encryption key if needed. */ int vl_resetkey(BUFFER *bp, const char *fname) { register int s; /* temporary return value */ /* flag the buffer as not having encryption */ ffdocrypt(FALSE); /* if we want to encrypt */ if (b_val(bp, MDCRYPT)) { char temp[NFILEN]; /* don't automatically inherit key from other buffers */ if (bp->b_cryptkey[0] != EOS && !b_is_argument(bp) && strcmp(lengthen_path(vl_strncpy(temp, fname, sizeof(temp))), bp->b_fname)) { char prompt[80]; (void) lsprintf(prompt, "Use crypt-key from %s", bp->b_bname); s = mlyesno(prompt); if (s != TRUE) return (s == FALSE); } /* make a key if we don't have one */ if (bp->b_cryptkey[0] == EOS) { s = get_encryption_key(bp->b_cryptkey, sizeof(bp->b_cryptkey)); if (s != TRUE) return (s == FALSE); } ffdocrypt(TRUE); vl_setup_encrypt(bp->b_cryptkey, seed); } return TRUE; }
/* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ int execute(int c, int f, int n) { int status; fn_t execfunc; /* if the keystroke is a bound function...do it */ execfunc = getbind(c); if (execfunc != NULL) { thisflag = 0; status = (*execfunc) (f, n); lastflag = thisflag; return status; } /* * If a space was typed, fill column is defined, the argument is non- * negative, wrap mode is enabled, and we are now past fill column, * and we are not read-only, perform word wrap. */ if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 && n >= 0 && getccol(FALSE) > fillcol && (curwp->w_bufp->b_mode & MDVIEW) == FALSE) execute(META | SPEC | 'W', FALSE, 1); #if PKCODE if ((c >= 0x20 && c <= 0x7E) /* Self inserting. */ #if IBMPC || (c >= 0x80 && c <= 0xFE)) { #else #if VMS || BSD || USG /* 8BIT P.K. */ || (c >= 0xA0 && c <= 0xFFFF)) { #else ) { #endif #endif #else if ((c >= 0x20 && c <= 0xFF)) { /* Self inserting. */ #endif if (n <= 0) { /* Fenceposts. */ lastflag = 0; return n < 0 ? FALSE : TRUE; } thisflag = 0; /* For the future. */ /* if we are in overwrite mode, not at eol, and next char is not a tab or we are at a tab stop, delete a char forword */ if (curwp->w_bufp->b_mode & MDOVER && curwp->w_doto < curwp->w_dotp->l_used && (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' || (curwp->w_doto) % 8 == 7)) ldelchar(1, FALSE); /* do the appropriate insertion */ if (c == '}' && (curbp->b_mode & MDCMOD) != 0) status = insbrace(n, c); else if (c == '#' && (curbp->b_mode & MDCMOD) != 0) status = inspound(); else status = linsert(n, c); #if CFENCE /* check for CMODE fence matching */ if ((c == '}' || c == ')' || c == ']') && (curbp->b_mode & MDCMOD) != 0) fmatch(c); #endif /* check auto-save mode */ if (curbp->b_mode & MDASAVE) if (--gacount == 0) { /* and save the file if needed */ upscreen(FALSE, 0); filesave(FALSE, 0); gacount = gasave; } lastflag = thisflag; return status; } TTbeep(); mlwrite("(Key not bound)"); /* complain */ lastflag = 0; /* Fake last flags. */ return FALSE; } /* * Fancy quit command, as implemented by Norm. If the any buffer has * changed do a write on that buffer and exit emacs, otherwise simply exit. */ int quickexit(int f, int n) { struct buffer *bp; /* scanning pointer to buffers */ struct buffer *oldcb; /* original current buffer */ int status; oldcb = curbp; /* save in case we fail */ bp = bheadp; while (bp != NULL) { if ((bp->b_flag & BFCHG) != 0 /* Changed. */ && (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */ && (bp->b_flag & BFINVS) == 0) { /* Real. */ curbp = bp; /* make that buffer cur */ mlwrite("(Saving %s)", bp->b_fname); #if PKCODE #else mlwrite("\n"); #endif if ((status = filesave(f, n)) != TRUE) { curbp = oldcb; /* restore curbp */ return status; } } bp = bp->b_bufp; /* on to the next buffer */ } quit(f, n); /* conditionally quit */ return TRUE; } static void emergencyexit(int signr) { quickexit(FALSE, 0); quit(TRUE, 0); } /* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int quit(int f, int n) { int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ || (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE) { #if (FILOCK && BSD) || SVR4 if (lockrel() != TRUE) { TTputc('\n'); TTputc('\r'); TTclose(); TTkclose(); exit(1); } #endif vttidy(); if (f) exit(n); else exit(GOOD); } mlwrite(""); return s; } /* * Begin a keyboard macro. * Error if not at the top level in keyboard processing. Set up variables and * return. */ int ctlxlp(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } mlwrite("(Start macro)"); kbdptr = &kbdm[0]; kbdend = kbdptr; kbdmode = RECORD; return TRUE; } /* * End keyboard macro. Check for the same limit conditions as the above * routine. Set up the variables and return to the caller. */ int ctlxrp(int f, int n) { if (kbdmode == STOP) { mlwrite("%%Macro not active"); return FALSE; } if (kbdmode == RECORD) { mlwrite("(End macro)"); kbdmode = STOP; } return TRUE; } /* * Execute a macro. * The command argument is the number of times to loop. Quit as soon as a * command gets an error. Return TRUE if all ok, else FALSE. */ int ctlxe(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } if (n <= 0) return TRUE; kbdrep = n; /* remember how many times to execute */ kbdmode = PLAY; /* start us in play mode */ kbdptr = &kbdm[0]; /* at the beginning */ return TRUE; } /* * Abort. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Sometimes called as a routine, to do general aborting of stuff. */ int ctrlg(int f, int n) { TTbeep(); kbdmode = STOP; mlwrite("(Aborted)"); return ABORT; }
/* Ask the user about every occurence of orig pattern and replace it with a repl pattern if the response is affirmative. */ int replace_all(UCS *orig, UCS *repl) { register int status = 0; UCS *b; UCS realpat[NPAT]; char utf8tmp[NPMT]; UCS *promptp; UCS prompt[NPMT]; int wrapt, n = 0; LINE *stop_line = curwp->w_dotp; int stop_offset = curwp->w_doto; EML eml; while (1) if (forscan(&wrapt, orig, stop_line, stop_offset, PTBEG)){ curwp->w_flag |= WFMOVE; /* put cursor back */ update(); (*term.t_rev)(1); get_pat_cases(realpat, orig); pputs(realpat, 1); /* highlight word */ (*term.t_rev)(0); fflush(stdout); snprintf(utf8tmp, NPMT, "Replace \""); b = utf8_to_ucs4_cpystr(utf8tmp); if(b){ ucs4_strncpy(prompt, b, NPMT); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } promptp = &prompt[ucs4_strlen(prompt)]; expandp(orig, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); b = utf8_to_ucs4_cpystr("\" with \""); if(b){ ucs4_strncpy(promptp, b, NPMT-(promptp-prompt)); promptp += ucs4_strlen(promptp); prompt[NPMT-1] = '\0'; fs_give((void **) &b); } expandp(repl, promptp, NPMT-(promptp-prompt)); prompt[NPMT-1] = '\0'; promptp += ucs4_strlen(promptp); if((promptp-prompt) < NPMT-1){ *promptp++ = '\"'; *promptp = '\0'; } prompt[NPMT-1] = '\0'; status = mlyesno(prompt, TRUE); /* ask user */ if (status == TRUE){ n++; chword(realpat, repl); /* replace word */ update(); }else{ chword(realpat, realpat); /* replace word by itself */ update(); if(status == ABORT){ /* if cancelled return */ eml.s = comatose(n); emlwrite("Replace All cancelled after %s changes", &eml); return (ABORT); /* ... else keep looking */ } } } else{ char *utf8; utf8 = ucs4_to_utf8_cpystr(orig); if(utf8){ eml.s = utf8; emlwrite(_("No more matches for \"%s\""), &eml); fs_give((void **) &utf8); } else emlwrite(_("No more matches"), NULL); return (FALSE); } }