/* * ex_file -- :f[ile] [name] * Change the file's name and display the status line. * * PUBLIC: int ex_file __P((SCR *, EXCMD *)); */ int ex_file(SCR *sp, EXCMD *cmdp) { char *p; FREF *frp; const char *np; size_t nlen; NEEDFILE(sp, cmdp); switch (cmdp->argc) { case 0: break; case 1: frp = sp->frp; /* Make sure can allocate enough space. */ INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1, np, nlen); if ((p = v_strdup(sp, np, nlen - 1)) == NULL) return (1); /* If already have a file name, it becomes the alternate. */ if (!F_ISSET(frp, FR_TMPFILE)) set_alt_name(sp, frp->name); /* Free the previous name. */ free(frp->name); frp->name = p; /* * The file has a real name, it's no longer a temporary, * clear the temporary file flags. */ F_CLR(frp, FR_TMPEXIT | FR_TMPFILE); /* Have to force a write if the file exists, next time. */ F_SET(frp, FR_NAMECHANGE); /* Notify the screen. */ (void)sp->gp->scr_rename(sp, sp->frp->name, 1); break; default: abort(); } msgq_status(sp, sp->lno, MSTAT_SHOWLAST); return (0); }
/* * v_status -- ^G * Show the file status. * * PUBLIC: int v_status __P((SCR *, VICMD *)); */ int v_status(SCR *sp, VICMD *vp) { (void)msgq_status(sp, vp->m_start.lno, MSTAT_SHOWLAST); return (0); }
/* * vs_resolve -- * Deal with message output. * * PUBLIC: int vs_resolve __P((SCR *, SCR *, int)); */ int vs_resolve(SCR *sp, SCR *csp, int forcewait) { EVENT ev; GS *gp; WIN *wp; MSGS *mp; VI_PRIVATE *vip; size_t oldy, oldx; int redraw; /* * Vs_resolve is called from the main vi loop and the refresh function * to periodically ensure that the user has seen any messages that have * been displayed and that any status lines are correct. The sp screen * is the screen we're checking, usually the current screen. When it's * not, csp is the current screen, used for final cursor positioning. */ gp = sp->gp; wp = sp->wp; vip = VIP(sp); if (csp == NULL) csp = sp; /* Save the cursor position. */ (void)gp->scr_cursor(csp, &oldy, &oldx); /* Ring the bell if it's scheduled. */ if (F_ISSET(gp, G_BELLSCHED)) { F_CLR(gp, G_BELLSCHED); (void)gp->scr_bell(sp); } /* Display new file status line. */ if (F_ISSET(sp, SC_STATUS)) { F_CLR(sp, SC_STATUS); msgq_status(sp, sp->lno, MSTAT_TRUNCATE); } /* Report on line modifications. */ mod_rpt(sp); /* * Flush any saved messages. If the screen isn't ready, refresh * it. (A side-effect of screen refresh is that we can display * messages.) Once this is done, don't trust the cursor. That * extra refresh screwed the pooch. */ if (gp->msgq.lh_first != NULL) { if (!F_ISSET(sp, SC_SCR_VI) && vs_refresh(sp, 1)) return (1); while ((mp = gp->msgq.lh_first) != NULL) { wp->scr_msg(sp, mp->mtype, mp->buf, mp->len); LIST_REMOVE(mp, q); free(mp->buf); free(mp); } F_SET(vip, VIP_CUR_INVALID); } switch (vip->totalcount) { case 0: redraw = 0; break; case 1: /* * If we're switching screens, we have to wait for messages, * regardless. If we don't wait, skip updating the modeline. */ if (forcewait) vs_scroll(sp, NULL, SCROLL_W); else F_SET(vip, VIP_S_MODELINE); redraw = 0; break; default: /* * If >1 message line in use, prompt the user to continue and * repaint overwritten lines. */ vs_scroll(sp, NULL, SCROLL_W); ev.e_event = E_REPAINT; ev.e_flno = vip->totalcount >= sp->rows ? 1 : sp->rows - vip->totalcount; ev.e_tlno = sp->rows; redraw = 1; break; } /* Reset the count of overwriting lines. */ vip->linecount = vip->lcontinue = vip->totalcount = 0; /* Redraw. */ if (redraw) (void)v_erepaint(sp, &ev); /* Restore the cursor position. */ (void)gp->scr_move(csp, oldy, oldx); return (0); }