📄 eebuff.c
字号:
/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International * This software is quasi-public; it may be used freely with * like software, but may NOT be sold or made part of licensed * products without permission of the author. *//* EEBUFF Buffer and Window functions. * Each buffer is an independent SB-string described by a * buffer structure. All buffer structures are allocated dynamically * and chained together starting from buf_head. */#include "elle.h"#if FX_FILLMODEextern int fill_mode;#endif#if FX_SKMACextern int kdef_mode;#endifstruct buffer *make_buf(), *find_buf(), *sel_mbuf(), *sel_nbuf();struct window *make_win();/* EFUN: "Select Buffer" *//* Select old buffer or create a new one. Defaults to previously * used buffer. */f_selbuffer(){ register char *ans; register struct buffer *b; if((b = last_buf) == cur_buf) /* If default same as current, */ if(!(b = sel_mbuf(b))) /* try to pick a more useful one. */ b = sel_nbuf(cur_buf); ans = ask("Select buffer (%s): ",b->b_name); if (ans == 0) /* he aborted */ return; if (*ans != '\0') /* Null string => use last buff */ { b = find_buf (ans); /* Else find/create one */ if (b == 0) b = make_buf (ans); } sel_buf(b); chkfree(ans);}#if FX_SELXBUFFER/* EFUN: "Select Existing Buffer" (not EMACS) - from IMAGEN config */static int findstr();f_selxbuffer(){ register char *ans; register struct buffer *b; b = last_buf; /* This is default */ ans = ask("Select existing buffer (%s): ", b->b_name); if (ans == 0) /* Aborted */ return; if (*ans != 0) { for (b = buf_head; b != 0; b = b->b_next) if (findstr(ans, b->b_name)) break; if (b == 0) ding("That isn't a substring of any buffer name!"); } chkfree(ans); if (b != 0) { saytoo(" => "); sayntoo(b->b_name); sel_buf(b); }}static intfindstr(str, instr) /* Find "str" in string "instr" */register char *str, *instr;{ register char *sp, *isp; while (*instr) { sp = str; isp = instr; while (*sp) if (*sp++ != *isp++) goto next; return(1);next: ++instr; } return(0);}#endif /*FX_SELXBUFFER*//* EFUN: "Kill Buffer" *//* Kill specified buffer - defaults to current buffer. * This code assumes a killed buffer will never be on a window list unless it * is pointed to by cur_buf or oth_win->w_buf!!!! */f_kbuffer(){ register struct buffer *b, *ob; register char *ans; if((ans = ask("Kill buffer: ")) == 0) return; if(*ans == 0) b = cur_buf; else if(*ans == SP) b = 0; else b = find_buf(ans); chkfree(ans); if(!b) { ding("No such buffer"); return; }#if IMAGEN if (b->b_flags & B_PERMANENT) { ding("Permanent buffer--cannot kill!"); return; } if (b->b_flags & B_MODIFIED) { if ((ans == ask("Buffer is modified; are you sure? ")) == 0) return; if(upcase(*ans) != 'Y') { chkfree(ans); return; } chkfree(ans); }#endif /*IMAGEN*/ if(b == cur_buf || (oth_win && (oth_win->w_buf == b))) { ob = last_buf; do { /* If default same as doomed buffer, try to pick * a more useful alternative. */ if((b == ob) && !(ob = sel_mbuf(b))) ob = sel_nbuf(b); ans = ask("Killing in-use buffer; select which other buffer (%s): ", ob->b_name); if(ans == 0) return; if(*ans) { if(*ans == SP) ob = 0; else ob = find_buf(ans); } chkfree(ans); if(!ob) { ding("No such buffer"); return; } } while (b == ob); /* B is buffer to kill, OB is buffer to replace it with */ if(oth_win && (oth_win->w_buf == b)) { f_othwind(); /* Select other one */ chg_buf(ob); /* Change to new buffer */ f_othwind(); } if(cur_buf == b) chg_buf(ob); } kill_buf(b); /* Die!!!! */ if(last_buf == b) last_buf = cur_buf;}/* EFUN: "List Buffers" *//* Display a list of all user buffers. Internal buffers, whose names * start with a space, are not shown. */f_listbufs(){ register struct buffer *b; register char *cp; register int i; struct buffer *tbuf, *savbuf; char temp[20]; /* First must set up special buffer... */ savbuf = cur_buf; chg_buf(tbuf = make_buf(" **SHOW**")); e_sputz("Buffers in this ELLE:\n\n"); for(b = buf_head; b; b = b->b_next) { cp = b->b_name; if(*cp == SP) continue; /* Ignore internal buffs */ e_sputz((b->b_flags&B_MODIFIED) ? "* " : " "); e_sputz(cp); /* Insert buffer name */ dottoa(temp,ex_blen(b)); /* Get buff-length string */ if((i = ((FNAMELEN > 14) ? 30 : 20) - strlen(cp) - strlen(temp)) > 0) e_insn(SP, i); e_sputz(" ("); e_sputz(temp); e_sputz(") "); if(cp = b->b_fn) e_sputz(cp);#if IMAGEN if (b->b_flags & B_CMODE) e_sputz(" (C)"); else if (b->b_flags & B_TEXTMODE) e_sputz(" (Text)"); else e_sputz(" (Fundamental)");#endif /*IMAGEN*/ e_putc(LF); } mk_showin(tbuf); /* Show this buffer in temp window */ chg_buf(savbuf); /* Return to real current buffer */ kill_buf(tbuf);}/* EFUN: "Buffer Not Modified" *//* Mark the current buffer as not modified. */f_bufnotmod(){ cur_buf -> b_flags &= ~B_MODIFIED; redp(RD_MODE);}#if FX_EOLMODE/* EFUN: "EOL CRLF Mode" (not EMACS) *//* Toggle the EOL mode of the current buffer.** LF EOL Mode means LF alone is an EOL.** CRLF EOL Mode means CRLF together is an EOL.*/f_eolmode(){ cur_buf->b_flags ^= B_EOLCRLF; /* Flip this bit */ say((cur_buf->b_flags & B_EOLCRLF) ? "EOL Mode is CRLF" /* If now on */ : "EOL Mode is LF"); /* If now off */ redp(RD_WINRES); /* Redo window for this buf */}#endif /*FX_EOLMODE*/#if FX_GOBEG/* EFUN: "Goto Beginning" */f_gobeg(){ e_gobob(); ed_setcur();}#endif /*FX_GOBEG*/#if FX_GOEND/* EFUN: "Goto End" */f_goend(){ e_goeob(); ed_setcur();}#endif /*FX_GOEND*/#if FX_WHATPAGE/* EFUN: "What Page" *//* Extra info added as per earlier ICONOGRAPHICS "What Buffer Position"** Reports on current position as follows:** Dot=<n>, Page <n> Line <n> (line <n> of <m>)*/f_whatpage(){ register chroff cnt; register int c; register int page, line; int lineatp; char tempstr[12], *dottoa (); saynow("Dot="); dottoa(tempstr, cur_dot); sayntoo(tempstr); e_gobob(); page = line = lineatp = 1; for (cnt = cur_dot; --cnt >= 0;) if ((c = e_getc()) == LF) ++line; else if (c == FF) { ++page; lineatp = line; } saytoo(", Page "); dottoa(tempstr, (chroff)page); saytoo(tempstr); saytoo(" Line "); dottoa(tempstr, (chroff)(1 + line - lineatp)); saytoo(tempstr); saytoo(" Col "); dottoa(tempstr, (chroff)indtion(cur_dot)); saytoo(tempstr); saytoo(" [line "); dottoa(tempstr, (chroff)line); saytoo(tempstr); sayntoo(" of "); /* Force out while scan rest */ for(e_gocur(); e_gonl() ; ++line) ; /* Count lines until EOF */ c = e_rgetc(); /* Remember what last char is */ dottoa(tempstr, (chroff)line); saytoo(tempstr); if (c != LF) /* Check last char */ saytoo(" (no EOL at EOF!)"); sayntoo("]"); e_gocur(); /* Back to original position */}#endif /*FX_WHATPAGE*/init_buf () /* init buffer stuff */{ buf_head = 0; lines_buf = cur_buf = make_buf(" **LINES**"); /* For sep_win */ e_insn('-',scr_wid-2); /* Fill with dashes */ last_buf = cur_buf = make_buf ("Main"); /* Make Main buffer */ init_win(); /* Now can init windows */}struct buffer *make_buf(bname) /* create buffer "bname" if it doesn't exist */char *bname;{ register struct buffer *b; register char *name; b = find_buf(name = bname); if (b) /* if it exists already */ return(b); b = (struct buffer *) memalloc(sizeof (struct buffer)); b -> b_next = buf_head; /* link it in */ buf_head = b; b->b_name = strdup(name); /* Allocate copy of name string */ b->b_dot = 0; /* Set dot to beg */ sb_open(b,(SBSTR *)0); /* Open buffer with null initial sbstring */ b->b_fn = 0; b->b_flags = 0; b->b_mode = cur_mode; /* Inherit current mode */ return(b);}struct buffer *find_buf(name) /* returns pointer to buffer of that name or 0 */char *name;{ register struct buffer *b = buf_head; while (b && strcmp(b->b_name, name)) b = b -> b_next; return(b);}sel_buf(b) /* select buffer, saving last */struct buffer *b;{ if(b != cur_buf) last_buf = cur_buf; chg_buf(b);}chg_buf (newbuf) /* change current buffer to newbuf */struct buffer *newbuf;{ register struct buffer *obuf, *nbuf; if ((nbuf = newbuf) == (obuf = cur_buf)) return; /* Do nothing if same buffers */ obuf->b_dot = cur_dot; cur_buf = nbuf; cur_mode = nbuf->b_mode; e_gosetcur(nbuf->b_dot); /* Set cur_dot and go there */ cur_win->w_buf = nbuf; cur_win->w_dot = cur_dot;#if IMAGEN cur_win->w_redp = RD_WINRES|RD_REDO;#else cur_win->w_redp = RD_WINRES; /* Reset flags - do complete update */#endif /*-IMAGEN*/ unlk_buf(obuf); /* Unlock previous buffer if can */ mark_p = 0; /* this is lazy */ redp(RD_MODE|RD_WINRES);}/* See if specified buffer belongs to any active window, and * if not then get it into an idle, unlocked state; this helps the * edit package compact and swap stuff out while it's not being used. * Assumes proper state of dot has been stored into b_dot. */unlk_buf(bufp)struct buffer *bufp;{ register struct buffer *b; register struct window *w; b = bufp; for(w = win_head; w; w = w->w_next) if(b == w->w_buf) return; /* Buffer is actively being shown */ sb_rewind((SBBUF *)b); /* Return to idle state */}/* SEL_NBUF(buf) - Select next user buffer. Ignores internal buffers. * Arg of 0 starts at beg of buffer list. Always returns * a buffer pointer - returns argument (which may be 0) * if found no other user buffers. * * SEL_MBUF(buf) - Select next modified buffer. * Returns buffer ptr to "next" modified buffer, if any. * Arg of 0 starts at beg of buffer list and scans all of them. * Returns 0 if no other modified buffers exist (unlike SEL_NBUF!) * Ignores internal buffers, whose names start with a space. *//* struct buffer *buf_mptr; */#if 0struct buffer *sel_mbuf(buf)struct buffer *buf;{ register struct buffer *b; register int sweep; sweep = 0; /* Make 2 sweeps only */ if(b = buf) b = b->b_next; do { if(b == 0) /* Initialize if needed */ b = buf_head; for(; b; b = b->b_next) if((b->b_flags & B_MODIFIED) && (*b->b_name != SP)) return((b == buf) ? 0 : b); } while(sweep++ != 0); return(0);}#endif /*COMMENT*/struct buffer *sel_mbuf(buf)register struct buffer *buf;{ register struct buffer *b, *b2; b = b2 = sel_nbuf(buf); do { if(b == buf) break; if(b->b_flags & B_MODIFIED) return(b); } while((b = sel_nbuf(b)) != b2); return(0);}struct buffer *sel_nbuf(buf)register struct buffer *buf;{ register struct buffer *b; b = buf; do { if(!b || !(b = b->b_next)) b = buf_head; if(*b->b_name != SP) break; } while (b != buf); return(b);}kill_buf(buf)struct buffer *buf;{ register struct buffer *b, *b1, *bt; b = buf; b1 = 0; for(bt = buf_head; bt && bt != b; bt = bt -> b_next) b1 = bt; if(bt == 0) { ring_bell(); errbarf("No such buffer"); /* Internal error */ return; } if (b1 == 0) buf_head = b->b_next; else b1->b_next = b->b_next; sbs_del(sb_close((SBBUF *)b)); /* Close buffer & delete sbstring */ sb_fdcls(-1); /* Make sweep for unused FD's */ if(b->b_fn) chkfree(b->b_fn); /* Flush filename if one */ chkfree(b->b_name); /* Flush name */ chkfree((char *)b); /* Flush buffer */}/* ZAP_BUFFER - Delete all of the buffer, but if it's been modified, * ask first. Returns 0 if user aborts. */zap_buffer(){#if IMAGEN extern struct buffer *exec_buf; /* in e_make.c */ if(cur_buf != exec_buf && cur_buf -> b_flags & B_MODIFIED)#else if(cur_buf -> b_flags & B_MODIFIED)#endif /*-IMAGEN*/ if(ask_kbuf(cur_buf) <= 0) return(0); /* Aborted */ ed_reset(); /* This takes care of redisplay too */ mark_p = 0;#if IMAGEN cur_buf->b_flags &= ~B_BACKEDUP; /* Clear backed-up flag */#endif return(1);}/* ASK_KBUF - Ask user "are you sure?" before killing a buffer. * Returns +1 if user says "yes" - OK to kill. * 0 if user aborts (^G) * -1 if user says "no". */ask_kbuf(buf)struct buffer *buf;{ register struct buffer *b; register char *s; register int ans; b = buf; s = ask("Buffer %s contains changes - forget them? ", b->b_name); if(s == 0) return(0); ans = (upcase(*s) == 'Y') ? 1 : -1; chkfree(s); return(ans);}/* Window stuff *//* Like EMACS, ELLE only provides at most two user windows. * The current user window is pointed to by user_win; * the "other" one is oth_win. If oth_win == 0, there is only one user * window. */#if FX_2MODEWINDSint sepmode_p = 0; /* Set true if separator window is a 2nd mode win */#endif/* EFUN: "Two Windows" */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -