static void frrec(UNDOREC *rec) { if (rec->del) { if (rec->len < SMALL) free(rec->small); else { B *b = rec->big; bonline(b); brm(b); } } enquef(UNDOREC, link, &frrecs, rec); }
int ucopy(BW *bw) { if (markv(1) && !square) { B *b = bcpy(markb, markk); yankdel(markb->byte, b); brm(b); if (lightoff) unmark(bw); return 0; } else { msgnw(bw->parent, joe_gettext(_("No block"))); return -1; } }
int uformat(BW *bw) { long indent; unsigned char *indents; B *buf; P *b; long curoff; int c; P *p, *q; p = pdup(bw->cursor, USTR "uformat"); p_goto_bol(p); /* Do nothing if we're not on a paragraph line */ if (pisnpara(bw, p)) { prm(p); return 0; } /* Move p to beginning of paragraph, bw->cursor to end of paragraph and * set curoff to original cursor offset within the paragraph */ pbop(bw, p); curoff = bw->cursor->byte - p->byte; pset(bw->cursor, p); peop(bw, bw->cursor); /* Ensure that paragraph ends on a beginning of a line */ if (!pisbol(bw->cursor)) binsc(bw->cursor, '\n'), pgetc(bw->cursor); /* Record indentation of second line of paragraph, of first line if there * is only one line */ q = pdup(p, USTR "uformat"); pnextl(q); if (q->line != bw->cursor->line) { P *r = pdup(q, USTR "uformat"); indent = nindent(bw, q, 0); pcol(r, indent); indents = brs(q, r->byte - q->byte); prm(r); } else { P *r = pdup(p, USTR "uformat"); int x, y; indent = nindent(bw, p, 1); /* allowing * and - here */ pcol(r, indent); indents = brs(p, r->byte - p->byte); prm(r); if (!bw->o.autoindent) { /* Don't indent second line of single-line paragraphs if autoindent is off */ int x = zlen(indents); while (x && (indents[x - 1] == ' ' || indents[x - 1] == '\t')) indents[--x] = 0; if (x) { indents[x++] = ' '; indents[x] = 0; } indent = txtwidth1(bw->o.charmap, bw->o.tab, indents, x); } for (x = 0; indents[x] && (indents[x] == ' ' || indents[x] == '\t'); ++x); y = zlen(indents); while (y && (indents[y - 1] == ' ' || indents[y - 1] == '\t')) --y; /* Don't duplicate if it looks like a bullet */ /* if (y && (indents[y - 1] == '*' || indents[y - 1] == '-') && (y == 1 || indents[y - 2] == ' ' || indents[y - 2] == '\t')) indents[y - 1] = ' '; */ /* Fix C comment */ if (indents[x] == '/' && indents[x + 1] == '*') indents[x] = ' '; } prm(q); /* But if the left margin is greater, we use that instead */ if (bw->o.lmargin > indent) { int x; for (x = 0; indents[x] == ' ' || indents[x] == '\t'; ++x); if (!indents[x]) { joe_free(indents); indent = bw->o.lmargin; indents = joe_malloc(indent+1); for (x = 0; x != indent; ++x) indents[x] = ' '; indents[x] = 0; } } /* Cut paragraph into new buffer */ /* New buffer needs to inherit UTF-8 and CR-LF options */ buf = bcpy(p, bw->cursor); buf->o.crlf = p->b->o.crlf; buf->o.charmap = p->b->o.charmap; bdel(p, bw->cursor); /* text is in buffer. insert it at cursor */ /* Do first line */ b = pdup(buf->bof, USTR "uformat"); while (!piseof(b)) { /* Set cursor position if we're at original offset */ if (b->byte == curoff) pset(bw->cursor, p); /* Get character from buffer */ c = pgetc(b); /* Stop if we found end of line */ if (c == '\n') { prgetc(b); break; } /* Stop if we found white-space followed by end of line */ if (joe_isblank(b->b->o.charmap, c) && piseolblank(b)) { prgetc(b); break; } /* Insert character, advance pointer */ binsc(p, c); pgetc(p); /* Do word wrap if we reach right margin */ if (piscol(p) > bw->o.rmargin && !joe_isblank(p->b->o.charmap,c)) { wrapword(bw, p, indent, bw->o.french, 1, indents); break; } } /* Do rest */ while (!piseof(b)) { c = brch(b); if (joe_isblank(b->b->o.charmap,c) || c == '\n') { int f = 0; P *d; int g; /* Set f if there are two spaces after . ? or ! instead of one */ /* (What is c was '\n'?) */ d=pdup(b, USTR "uformat"); g=prgetc(d); if (g=='.' || g=='?' || g=='!') { f = 1; /* pset(d,b); pgetc(d); if (c == '\n' || piseol(d) || joe_isspace(bw->b->o.charmap,brch(d))) { f = 1; } */ } prm(d); /* Skip past the whitespace. Skip over indentations */ loop: c = brch(b); if (c == '\n') { if (b->byte == curoff) pset(bw->cursor, p); pgetc(b); while (cpara(bw, (c=brch(b)))) { if (b->byte == curoff) pset(bw->cursor, p); pgetc(b); } } if (joe_isblank(b->b->o.charmap,c)) { if(b->byte == curoff) pset(bw->cursor, p); pgetc(b); goto loop; } /* Insert proper amount of whitespace */ if (!piseof(b)) { if (f && !bw->o.french) binsc(p, ' '), pgetc(p); binsc(p, ' '); pgetc(p); } } else { /* Insert characters of word and wrap if necessary */ if (b->byte == curoff) pset(bw->cursor, p); binsc(p, pgetc(b)); pgetc(p); if (piscol(p) > bw->o.rmargin) wrapword(bw, p, indent, bw->o.french, 1, indents); } } binsc(p, '\n'); prm(p); brm(buf); joe_free(indents); return 0; }
void undodel(UNDO *undo, long where, B *b) { UNDOREC *rec; long size = b->eof->byte; if (inredo) { brm(b); return; } if (!inundo) if (undo->ptr && undo->ptr != &undo->recs) undoover(undo); yankdel(where, b); /* Store in undo buffer */ rec = undo->recs.link.prev; if (rec != &undo->recs && rec->min && rec->del && where == rec->where) { if (rec->len + size >= SMALL) { if (rec->len < SMALL) { rec->big = bmk(NULL); binsm(rec->big->bof, rec->small, (int) rec->len); boffline(rec->big); free(rec->small); } bonline(rec->big); binsb(rec->big->eof, b); boffline(rec->big); } else { rec->small = (unsigned char *) joe_realloc(rec->small, rec->len + size); brmem(b->bof, rec->small + rec->len, (int) size); brm(b); } rec->len += size; } else if (rec != &undo->recs && rec->min && rec->del && where + size == rec->where) { if (rec->len + size >= SMALL) { if (rec->len < SMALL) { rec->big = bmk(NULL); binsm(rec->big->bof, rec->small, (int) rec->len); boffline(rec->big); free(rec->small); } bonline(rec->big); binsb(rec->big->bof, b); boffline(rec->big); } else { rec->small = (unsigned char *) joe_realloc(rec->small, rec->len + size); memmove(rec->small + size, rec->small, (int) rec->len); brmem(b->bof, rec->small, (int) size); brm(b); } rec->len += size; rec->where = where; } else { rec = alrec(); if (size < SMALL) { rec->small = (unsigned char *) joe_malloc(size); brmem(b->bof, rec->small, (int) b->eof->byte); brm(b); } else { rec->big = b; boffline(b); } if (!undo->first) undo->first = rec; undo->last = rec; rec->where = where; rec->min = 1; rec->unit = NULL; rec->len = size; rec->del = 1; rec->changed = undo->b->changed; enqueb(UNDOREC, link, &undo->recs, rec); } }