📄 bw.c
字号:
/* * Edit buffer window generation * Copyright * (C) 1992 Joseph H. Allen * * This file is part of JOE (Joe's Own Editor) */#include "types.h"/* Display modes */int dspasis = 0;int marking = 0;static P *getto(P *p, P *cur, P *top, long int line){ if (p == NULL) { P *best = cur; long dist = MAXLONG; long d; d = (line >= cur->line ? line - cur->line : cur->line - line); if (d < dist) { dist = d; best = cur; } d = (line >= top->line ? line - top->line : top->line - line); if (d < dist) { dist = d; best = top; } p = pdup(best, USTR "getto"); p_goto_bol(p); } while (line > p->line) if (!pnextl(p)) break; if (line < p->line) { while (line < p->line) pprevl(p); p_goto_bol(p); } return p;}/* Scroll window to follow cursor */int mid = 0;/* For hex */void bwfllwh(BW *w){ /* Top must be a muliple of 16 bytes */ if (w->top->byte%16) { pbkwd(w->top,w->top->byte%16); } /* Move backward */ if (w->cursor->byte < w->top->byte) { long new_top = w->cursor->byte/16; if (mid) { if (new_top >= w->h / 2) new_top -= w->h / 2; else new_top = 0; } if (w->top->byte/16 - new_top < w->h) nscrldn(w->t->t, w->y, w->y + w->h, (int) (w->top->byte/16 - new_top)); else msetI(w->t->t->updtab + w->y, 1, w->h); pgoto(w->top,new_top*16); } /* Move forward */ if (w->cursor->byte >= w->top->byte+(w->h*16)) { long new_top; if (mid) { new_top = w->cursor->byte/16 - w->h / 2; } else { new_top = w->cursor->byte/16 - (w->h - 1); } if (new_top - w->top->byte/16 < w->h) nscrlup(w->t->t, w->y, w->y + w->h, (int) (new_top - w->top->byte/16)); else { msetI(w->t->t->updtab + w->y, 1, w->h); } pgoto(w->top, new_top*16); } /* Adjust scroll offset */ if (w->cursor->byte%16+60 < w->offset) { w->offset = w->cursor->byte%16+60; msetI(w->t->t->updtab + w->y, 1, w->h); } else if (w->cursor->byte%16+60 >= w->offset + w->w) { w->offset = w->cursor->byte%16+60 - (w->w - 1); msetI(w->t->t->updtab + w->y, 1, w->h); }}/* For text */void bwfllwt(BW *w){ P *newtop; if (!pisbol(w->top)) { p_goto_bol(w->top); } if (w->cursor->line < w->top->line) { newtop = pdup(w->cursor, USTR "bwfllwt"); p_goto_bol(newtop); if (mid) { if (newtop->line >= w->h / 2) pline(newtop, newtop->line - w->h / 2); else pset(newtop, newtop->b->bof); } if (w->top->line - newtop->line < w->h) nscrldn(w->t->t, w->y, w->y + w->h, (int) (w->top->line - newtop->line)); else { msetI(w->t->t->updtab + w->y, 1, w->h); } pset(w->top, newtop); prm(newtop); } else if (w->cursor->line >= w->top->line + w->h) { /* newtop = pdup(w->top); */ /* getto() creates newtop */ if (mid) newtop = getto(NULL, w->cursor, w->top, w->cursor->line - w->h / 2); else newtop = getto(NULL, w->cursor, w->top, w->cursor->line - (w->h - 1)); if (newtop->line - w->top->line < w->h) nscrlup(w->t->t, w->y, w->y + w->h, (int) (newtop->line - w->top->line)); else { msetI(w->t->t->updtab + w->y, 1, w->h); } pset(w->top, newtop); prm(newtop); }/* Adjust column */ if (w->cursor->xcol < w->offset) { long target = w->cursor->xcol; if (target < 5) target = 0; else { target -= 5; target -= (target % 5); } w->offset = target; msetI(w->t->t->updtab + w->y, 1, w->h); } if (w->cursor->xcol >= w->offset + w->w) { w->offset = w->cursor->xcol - (w->w - 1); msetI(w->t->t->updtab + w->y, 1, w->h); }}/* For either */void bwfllw(BW *w){ if (w->o.hex) bwfllwh(w); else bwfllwt(w);}/* Determine highlighting state of a particular line on the window. If the state is not known, it is computed and the state for all of the remaining lines of the window are also recalculated. */HIGHLIGHT_STATE get_highlight_state(BW *w, P *p, int line){ HIGHLIGHT_STATE state; if(!w->o.highlight || !w->o.syntax) { invalidate_state(&state); return state; } return lattr_get(w->db, w->o.syntax, p, line); /* Old way... */#ifdef junk ln = line; lattr_get(w->db, &ln, &state); if (ln != line) { tmp = pdup(p, USTR "get_highlight_state"); pline(tmp, ln); while (tmp->line < line && !piseof(tmp)) { state = parse(w->o.syntax, tmp, state); } if (tmp->line == line) lattr_set(w->db, line, state); prm(tmp); } return state;#endif#ifdef junk P *tmp = 0; HIGHLIGHT_STATE state; /* Screen y position of requested line */ int y = line-w->top->line+w->y; if(!w->o.highlight || !w->o.syntax) { invalidate_state(&state); return state; } /* If we know the state, just return it */ if (w->parent->t->t->syntab[y].state>=0) return w->parent->t->t->syntab[y]; /* Scan upwards until we have a line with known state or we're on the first line */ while (y > w->y && w->parent->t->t->syntab[y].state < 0) --y; /* If we don't have state for this line, calculate by going 100 lines back */ if (w->parent->t->t->syntab[y].state<0) { /* We must be on the top line */ clear_state(&state); tmp = pdup(w->top, USTR "get_highlight_state"); if(w->o.syntax->sync_lines >= 0 && tmp->line > w->o.syntax->sync_lines) pline(tmp, tmp->line-w->o.syntax->sync_lines); else p_goto_bof(tmp); while(tmp->line!=y-w->y+w->top->line) state = parse(w->o.syntax,tmp,state); w->parent->t->t->syntab[y] = state; w->parent->t->t->updtab[y] = 1; prm(tmp); } /* Color to end of screen */ tmp = pdup(w->top, USTR "get_highlight_state"); pline(tmp, y-w->y+w->top->line); state = w->parent->t->t->syntab[y]; while(tmp->line!=w->top->line+w->h-1 && !piseof(tmp)) { state = parse(w->o.syntax,tmp,state); w->parent->t->t->syntab[++y] = state; w->parent->t->t->updtab[y] = 1; /* This could be smarter: update only if we changed what was there before */ } prm(tmp); while(y<w->y+w->h-1) { w->parent->t->t->syntab[++y] = state; } /* Line after window */ /* state = parse_c(state,syn,tmp); */ /* If we changed, fix other windows */ /* w->state = state; */ /* Return state of requested line */ y = line - w->top->line + w->y; return w->parent->t->t->syntab[y];#endif}/* Scroll a buffer window after an insert occured. 'flg' is set to 1 if * the first line was split */void bwins(BW *w, long int l, long int n, int flg){ /* If highlighting is enabled... */ if (w->o.highlight && w->o.syntax) { /* Invalidate cache */ /* lattr_cut(w->db, l + 1); */ /* Force updates */ if (l < w->top->line) { msetI(w->t->t->updtab + w->y, 1, w->h); } else if ((l + 1) < w->top->line + w->h) { int start = l + 1 - w->top->line; int size = w->h - start; msetI(w->t->t->updtab + w->y + start, 1, size); } } /* Scroll */ if (l + flg + n < w->top->line + w->h && l + flg >= w->top->line && l + flg <= w->b->eof->line) { if (flg) w->t->t->sary[w->y + l - w->top->line] = w->t->t->li; nscrldn(w->t->t, (int) (w->y + l + flg - w->top->line), w->y + w->h, (int) n); } /* Force update of lines in opened hole */ if (l < w->top->line + w->h && l >= w->top->line) { if (n >= w->h - (l - w->top->line)) { msetI(w->t->t->updtab + w->y + l - w->top->line, 1, w->h - (int) (l - w->top->line)); } else { msetI(w->t->t->updtab + w->y + l - w->top->line, 1, (int) n + 1); } }}/* Scroll current windows after a delete */void bwdel(BW *w, long int l, long int n, int flg){ /* If highlighting is enabled... */ if (w->o.highlight && w->o.syntax) { /* lattr_cut(w->db, l + 1); */ if (l < w->top->line) { msetI(w->t->t->updtab + w->y, 1, w->h); } else if ((l + 1) < w->top->line + w->h) { int start = l + 1 - w->top->line; int size = w->h - start; msetI(w->t->t->updtab + w->y + start, 1, size); } } /* Update the line where the delete began */ if (l < w->top->line + w->h && l >= w->top->line) w->t->t->updtab[w->y + l - w->top->line] = 1; /* Update the line where the delete ended */ if (l + n < w->top->line + w->h && l + n >= w->top->line) w->t->t->updtab[w->y + l + n - w->top->line] = 1; if (l < w->top->line + w->h && (l + n >= w->top->line + w->h || (l + n == w->b->eof->line && w->b->eof->line >= w->top->line + w->h))) { if (l >= w->top->line) /* Update window from l to end */ msetI(w->t->t->updtab + w->y + l - w->top->line, 1, w->h - (int) (l - w->top->line)); else /* Update entire window */ msetI(w->t->t->updtab + w->y, 1, w->h); } else if (l < w->top->line + w->h && l + n == w->b->eof->line && w->b->eof->line < w->top->line + w->h) { if (l >= w->top->line) /* Update window from l to end of file */ msetI(w->t->t->updtab + w->y + l - w->top->line, 1, (int) n); else /* Update from beginning of window to end of file */ msetI(w->t->t->updtab + w->y, 1, (int) (w->b->eof->line - w->top->line)); } else if (l + n < w->top->line + w->h && l + n > w->top->line && l + n < w->b->eof->line) { if (l + flg >= w->top->line) nscrlup(w->t->t, (int) (w->y + l + flg - w->top->line), w->y + w->h, (int) n); else nscrlup(w->t->t, w->y, w->y + w->h, (int) (l + n - w->top->line)); }}/* Update a single line */static int lgen(SCRN *t, int y, int *screen, int *attr, int x, int w, P *p, long int scr, long int from, long int to,HIGHLIGHT_STATE st,BW *bw) /* Screen line address */ /* Window */ /* Buffer pointer */ /* Starting column to display */ /* Range for marked block */{ int ox = x; int tach; int done = 1; long col = 0; long byte = p->byte; unsigned char *bp; /* Buffer pointer, 0 if not set */ int amnt; /* Amount left in this segment of the buffer */ int c, ta, c1; unsigned char bc; int ungetit = -1; struct utf8_sm utf8_sm; int *syn = 0; P *tmp; int idx=0; int atr = BG_COLOR(bg_text); utf8_init(&utf8_sm); if(st.state!=-1) { tmp=pdup(p, USTR "lgen"); p_goto_bol(tmp); parse(bw->o.syntax,tmp,st); syn = attr_buf; prm(tmp); }/* Initialize bp and amnt from p */ if (p->ofst >= p->hdr->hole) { bp = p->ptr + p->hdr->ehole + p->ofst - p->hdr->hole; amnt = SEGSIZ - p->hdr->ehole - (p->ofst - p->hdr->hole); } else { bp = p->ptr + p->ofst; amnt = p->hdr->hole - p->ofst; } if (col == scr) goto loop; lp: /* Display next character */ if (amnt) do { if (ungetit== -1) bc = *bp++; else { bc = ungetit; ungetit = -1; } if(st.state!=-1) { atr = syn[idx++]; if (!((atr & BG_VALUE) >> BG_SHIFT)) atr |= BG_COLOR(bg_text); } if (p->b->o.crlf && bc == '\r') { ++byte; if (!--amnt) { pppl: if (bp == p->ptr + SEGSIZ) { if (pnext(p)) { bp = p->ptr; amnt = p->hdr->hole; } else goto nnnl; } else { bp = p->ptr + p->hdr->ehole; amnt = SEGSIZ - p->hdr->ehole; if (!amnt) goto pppl; } } if (*bp == '\n') { ++bp; ++byte; ++amnt; goto eobl; } nnnl: --byte; ++amnt; } if (square)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -