📄 util.c
字号:
/*************************************************************************** * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * * is provided to you without charge, and with no warranty. You may give * * away copies of JOVE, including sources, provided that this notice is * * included in all the files. * ***************************************************************************/#include "jove.h"#include "ctype.h"#include "termcap.h"#include "disp.h"#include "fp.h"#include <signal.h>#include <errno.h>#ifdef MAC# include "mac.h"#else# ifdef STDARGS# include <stdarg.h># else# include <varargs.h># endif#endif#ifdef MSDOS#include <time.h>#endif#ifndef IBMPCconst#endifstruct cmd *FindCmd(proc)register void (*proc) proto((void));{ register const struct cmd *cp; for (cp = commands; cp->Name; cp++) if (cp->c_proc == proc) return cp; return NULL;}bool Interactive = NO; /* True when we invoke with the command handler? */data_obj *LastCmd;char *ProcFmt = ": %f ";voidExecCmd(cp)register data_obj *cp;{ LastCmd = cp; if (cp->Type & MAJOR_MODE) { SetMajor((cp->Type >> 8)); } else if (cp->Type & MINOR_MODE) { TogMinor((cp->Type >> 8)); } else switch (cp->Type&TYPEMASK) { case MACRO: do_macro((struct macro *) cp); break; case FUNCTION: { register struct cmd *cmd = (struct cmd *) cp; if (cmd->c_proc) { if ((cmd->Type & MODIFIER) && (BufMinorMode(curbuf, ReadOnly))) { rbell(); message("[Buffer is read-only]"); } else (*cmd->c_proc)(); } } }}Line *lastline(lp)register Line *lp;{ register Line *next; while ((next = lp->l_next) != NULL) lp = next; return lp;}char key_strokes[100], *keys_p = key_strokes;voidpp_key_strokes(buffer, size)char *buffer;size_t size;{ char *buf_end = buffer + size - 1, *kp = key_strokes, c; *buffer = '\0'; while ((c = *kp++) != '\0') { swritef(buffer, (size_t) (buf_end-buffer), "%p ", c); buffer += strlen(buffer); if (buffer >= buf_end) break; }}private int *slowp = NULL; /* for waitchar() */private SIGRESULTslowpoke(junk)int junk;{ int save_errno = errno; /* Subtle, but necessary! */ char buffer[100]; if (slowp) *slowp = YES; pp_key_strokes(buffer, sizeof (buffer)); f_mess(buffer); errno = save_errno; SIGRETURN;}#ifdef UNIX# ifdef BSD4_2# define N_SEC 1 /* will be precisely 1 second on 4.2 */# else# define N_SEC 2 /* but from 1 to 2 seconds otherwise */# endif#else /* !UNIX */# define N_SEC 1int in_macro();#endif /* !UNIX */intwaitchar(slow)int *slow;{ int c;#ifdef UNIX unsigned int old_time; SIGRESULT (*oldproc) proto((int));#else /* !UNIX */ long sw, time();#endif /* !UNIX */ slowp = slow; if (in_macro()) /* make macros faster ... */ return getch(); /* If slow is a valid pointer and it's value is yes, then we know we have already been slow during this sequence, so we just wait for the character and then echo it. */ if (slow != NULL && *slow == YES) { c = getch(); slowpoke(0); return c; }#ifdef UNIX oldproc = signal(SIGALRM, slowpoke); if ((old_time = alarm((unsigned) N_SEC)) == 0) old_time = UpdFreq; c = getch(); (void) alarm(old_time); (void) signal(SIGALRM, oldproc); if (slow != NULL && *slow == YES) slowpoke(0); return c;#else /* !UNIX */#ifdef MAC Keyonly = YES; if (charp() || in_macro()) { c = getch(); /* to avoid flicker */ if (slow != NULL && *slow == YES) slowpoke(); return c; }#endif time(&sw); sw += N_SEC; while (time(NULL) <= sw) if (charp() || in_macro()) return getch();#ifdef MAC menus_off();#endif slowpoke(); c = getch(); slowpoke(); return c;#endif /* !UNIX */}char *StrIndex(dir, buf, charpos, what)int dir; /* FORWARD or BACKWARD */register char *buf;int charpos;register int what;{ register char *cp = &buf[charpos]; register int c; if (dir > 0) { while ((c = *cp++) != '\0') if ((c == what) != '\0') return (cp - 1); } else { while (cp >= buf && (c = *cp--)!='\0') if (c == what) return (cp + 1); } return NULL;}boolblnkp(buf)register char *buf;{ register char c; do ; while ((c = *buf++)!='\0' && (c == ' ' || c == '\t')); return c == 0; /* It's zero if we got to the end of the Line */}boolwithin_indent(){ register char c; register int i; i = curchar; do ; while (--i >= 0 && ((c = linebuf[i]) == ' ' || c == '\t')); return i < 0; /* it's < 0 if we got to the beginning */}Line *next_line(line, num)register Line *line;register int num;{ if (num < 0) return prev_line(line, -num); if (line) while (--num >= 0 && line->l_next != NULL) line = line->l_next; return line;}Line *prev_line(line, num)register Line *line;register int num;{ if (num < 0) return next_line(line, -num); if (line) while (--num >= 0 && line->l_prev != NULL) line = line->l_prev; return line;}voidDotTo(line, col)Line *line;int col;{ Bufpos bp; bp.p_line = line; bp.p_char = col; SetDot(&bp);}/* If bp->p_line is != current line, then save current line. Then set dot to bp->p_line, and if they weren't equal get that line into linebuf. */voidSetDot(bp)register Bufpos *bp;{ register int notequal; if (bp == NULL) return; notequal = bp->p_line != curline; if (notequal) lsave(); if (bp->p_line) curline = bp->p_line; if (notequal) getDOT(); curchar = bp->p_char; if (curchar > length(curline)) curchar = length(curline);}voidToLast(){ SetLine(curbuf->b_last); Eol();}int MarkThresh = 22; /* average screen size ... */static int line_diff;intLineDist(nextp, endp)register Line *nextp, *endp;{ (void) inorder(nextp, 0, endp, 0); return line_diff;}intinorder(nextp, char1, endp, char2)register Line *nextp, *endp;int char1, char2;{ register Line *prevp = nextp; line_diff = 0; if (nextp == endp) return char1 < char2; while (nextp && prevp) { nextp = nextp->l_next; prevp = prevp->l_prev; line_diff += 1; if (nextp == endp) return TRUE; if (prevp == endp) return FALSE; } while (nextp!=NULL && nextp!=endp) { nextp = nextp->l_next; line_diff += 1; } while (prevp!=NULL && prevp!=endp) { prevp = prevp->l_prev; line_diff += 1; } /* nextp == prevp implies both are NULL: the lines are not ordered */ return nextp==prevp? -1 : nextp==endp;}voidPushPntp(line)register Line *line;{ if (LineDist(curline, line) >= MarkThresh) set_mark();}voidToFirst(){ SetLine(curbuf->b_first);}intlength(line)Line *line;{ return strlen(lcontents(line));}voidto_word(dir)register int dir;{ register char c; if (dir == FORWARD) { while ((c = linebuf[curchar]) != '\0' && !jisword(c)) curchar += 1; if (eolp()) { if (curline->l_next == NULL) return; SetLine(curline->l_next); to_word(dir); return; } } else { while (!bolp() && (c = linebuf[curchar - 1], !jisword(c))) curchar -= 1; if (bolp()) { if (curline->l_prev == NULL) return; SetLine(curline->l_prev); Eol(); to_word(dir); } }}/* Are there any modified buffers? Allp means include B_PROCESS buffers in the check. */boolModBufs(allp)bool allp;{ register Buffer *b; for (b = world; b != NULL; b = b->b_next) if (b->b_type != B_SCRATCH && (b->b_type == B_FILE || allp) && IsModified(b)) return YES; return NO;}char *filename(b)register Buffer *b;{ return b->b_fname ? pr_name(b->b_fname, YES) : "[No file]";}char *itoa(num)register int num;{ static char line[15]; swritef(line, sizeof(line), "%d", num); return line;}intmin(a, b)register int a, b;{ return (a < b) ? a : b;}intmax(a, b)register int a, b;{ return (a > b) ? a : b;}voidtiewind(w, bp)register Window *w;register Buffer *bp;{ int not_tied = (w->w_bufp != bp); UpdModLine = YES; /* kludge ... but speeds things up considerably */ w->w_line = bp->b_dot; w->w_char = bp->b_char; w->w_bufp = bp; if (not_tied) CalcWind(w); /* ah, this has been missing since the beginning of time! */}char *lcontents(line)register Line *line;{ if (line == curline) return linebuf; else return lbptr(line);}char *ltobuf(line, buf)Line *line;char *buf;{ if (line == curline) { if (buf != linebuf) strcpy(buf, linebuf); Jr_Len = strlen(linebuf); } else getline(line->l_dline, buf); return buf;}voidDOTsave(buf)Bufpos *buf;{ buf->p_line = curline; buf->p_char = curchar;}/* Return none-zero if we had to rearrange the order. */boolfixorder(line1, char1, line2, char2)register Line **line1, **line2;register int *char1, *char2;{ Line *tline; int tchar; if (inorder(*line1, *char1, *line2, *char2)) return NO; tline = *line1; tchar = *char1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -