/* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ globle int execute( void *theEnv, int c, int f, int n) { register KEYTAB *ktp; register int status; ktp = &keytab[0]; /* Look in key table. */ while (ktp < &keytab[NKEYTAB]) { if (ktp->k_code == c) { thisflag = 0; status = (*ktp->k_fp)(theEnv,f, n); lastflag = thisflag; return (status); } ++ktp; } /* * If a space was typed, fill column is defined, the argument is non- * negative, and we are now past fill column, perform word wrap. */ if (c == ' ' && fillcol > 0 && n>=0 && getccol(FALSE) > fillcol) wrapword(theEnv); if ((c>=0x20 && c<=0x7E) /* Self inserting. */ || (c>=0xA0 && c<=0xFE)) { if (n <= 0) { /* Fenceposts. */ lastflag = 0; return (n<0 ? FALSE : TRUE); } thisflag = 0; /* For the future. */ status = linsert(theEnv,n, c); lastflag = thisflag; return (status); } lastflag = 0; /* Fake last flags. */ return (FALSE); }
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; }
/* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ int execute(UCS c, int f, int n) { KEYTAB *ktp; int status, ww; ktp = (Pmaster) ? &keytab[0] : &pkeytab[0]; while (ktp->k_fp != NULL) { if (ktp->k_code == c) { if(lastflag&CFFILL){ curwp->w_flag |= WFMODE; if(Pmaster == NULL) sgarbk = TRUE; } thisflag = 0; status = (*ktp->k_fp)(f, n); if((lastflag & CFFILL) && !(thisflag & CFFILL)) fdelete(); if((lastflag & CFFLBF) && !(thisflag & CFFLBF)) kdelete(); lastflag = thisflag; /* * Reset flag saying wrap should open a new line whenever * we execute a command (as opposed to just typing in text). * However, if that command leaves us in the same line on the * screen, then don't reset. */ if(curwp->w_flag & (WFMOVE | WFHARD)) curbp->b_flag |= BFWRAPOPEN; /* wrap should open new line */ return (status); } ++ktp; } if(lastflag & CFFILL) /* blat unusable fill data */ fdelete(); if(lastflag & CFFLBF) kdelete(); if (VALID_KEY(c)) { /* Self inserting. */ if (n <= 0) { /* Fenceposts. */ lastflag = 0; return (n<0 ? FALSE : TRUE); } thisflag = 0; /* For the future. */ /* do the appropriate insertion */ /* pico never does C mode, this is simple */ status = linsert(n, c); /* * Check to make sure we didn't go off of the screen * with that character. Take into account tab expansion. * If so wrap the line... */ if(curwp->w_bufp->b_mode & MDWRAP){ int j, wid; wid = 0; for(j = 0; j < llength(curwp->w_dotp); j++) if(ucs4_isspace(lgetc(curwp->w_dotp, j).c)){ if(lgetc(curwp->w_dotp, j).c == TAB){ ++wid; while(wid & 0x07) ++wid; } else ++wid; } else{ ww = wcellwidth((UCS) lgetc(curwp->w_dotp, j).c); wid += (ww >= 0 ? ww : 1); if(wid > fillcol){ wrapword(); break; } } } lastflag = thisflag; return (status); } unknown_command(c); lastflag = 0; /* Fake last flags. */ return (FALSE); }