#include <sys/queue.h>
#include <ctype.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "def.h"
static int fillcol = 70;
#define MAXWORD 256
static int findpara(void);
static int do_gotoeop(int, int, int *);
int
gotobop(int f, int n)
{
int col, nospace;
if (n < 0)
return (gotoeop(f, -n));
while (n-- > 0) {
nospace = 0;
while (lback(curwp->w_dotp) != curbp->b_headp) {
curwp->w_doto = 0;
col = 0;
while (col < llength(curwp->w_dotp) &&
(isspace(lgetc(curwp->w_dotp, col))))
col++;
if (col >= llength(curwp->w_dotp)) {
if (nospace)
break;
} else
nospace = 1;
curwp->w_dotline--;
curwp->w_dotp = lback(curwp->w_dotp);
}
}
curwp->w_rflag |= WFMOVE;
return (TRUE);
}
int
gotoeop(int f, int n)
{
int i;
return(do_gotoeop(f, n, &i));
}
int
do_gotoeop(int f, int n, int *i)
{
int col, nospace, j = 0;
if (n < 0)
return (gotobop(f, -n));
while (n-- > 0) {
*i = ++j;
nospace = 0;
while (lforw(curwp->w_dotp) != curbp->b_headp) {
col = 0;
curwp->w_doto = 0;
while (col < llength(curwp->w_dotp) &&
(isspace(lgetc(curwp->w_dotp, col))))
col++;
if (col >= llength(curwp->w_dotp)) {
if (nospace)
break;
} else
nospace = 1;
curwp->w_dotp = lforw(curwp->w_dotp);
curwp->w_dotline++;
}
}
if (lforw(curwp->w_dotp) == curbp->b_headp) {
gotoeol(FFRAND, 1);
curwp->w_rflag |= WFMOVE;
return (FALSE);
}
curwp->w_rflag |= WFMOVE;
return (TRUE);
}
int
fillpara(int f, int n)
{
int c;
int wordlen;
int clength;
int i;
int eopflag;
int firstflag;
int newlength;
int eolflag;
int retval;
struct line *eopline;
char wbuf[MAXWORD];
if (n == 0)
return (TRUE);
undo_boundary_enable(FFRAND, 0);
(void)gotoeop(FFRAND, 1);
if (curwp->w_doto != 0) {
(void)lnewline();
eopline = lforw(curwp->w_dotp);
} else
eopline = curwp->w_dotp;
(void)gotobop(FFRAND, 1);
while (inword() == 0 && forwchar(FFRAND, 1));
clength = curwp->w_doto;
wordlen = 0;
firstflag = TRUE;
eopflag = FALSE;
while (!eopflag) {
if ((eolflag = (curwp->w_doto == llength(curwp->w_dotp)))) {
c = ' ';
if (lforw(curwp->w_dotp) == eopline)
eopflag = TRUE;
} else
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag) {
retval = FALSE;
goto cleanup;
}
if (c != ' ' && c != '\t') {
if (wordlen < MAXWORD - 1)
wbuf[wordlen++] = c;
else {
ewprintf("Word too long!");
}
} else if (wordlen) {
newlength = clength + 1 + wordlen;
if (dblspace && (!eopflag && ((eolflag ||
curwp->w_doto == llength(curwp->w_dotp) ||
(c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' '
|| c == '\t') && (ISEOSP(wbuf[wordlen - 1]) ||
(wbuf[wordlen - 1] == ')' && wordlen >= 2 &&
ISEOSP(wbuf[wordlen - 2])))) &&
wordlen < MAXWORD - 1))
wbuf[wordlen++] = ' ';
if (newlength <= fillcol) {
if (!firstflag) {
(void)linsert(1, ' ');
++clength;
}
firstflag = FALSE;
} else {
if (curwp->w_doto > 0 &&
lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') {
curwp->w_doto -= 1;
(void)ldelete((RSIZE) 1, KNONE);
}
(void)lnewline();
clength = 0;
}
for (i = 0; i < wordlen; i++) {
(void)linsert(1, wbuf[i]);
++clength;
}
wordlen = 0;
}
}
(void)lnewline();
(void)backchar(FFRAND, 1);
retval = TRUE;
cleanup:
undo_boundary_enable(FFRAND, 1);
return (retval);
}
int
killpara(int f, int n)
{
int lineno, status;
if (n == 0)
return (TRUE);
if (findpara() == FALSE)
return (TRUE);
(void)gotobop(FFRAND, 1);
lineno = curwp->w_dotline;
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
(void)gotoeop(FFRAND, n);
if ((status = killregion(FFRAND, 1)) != TRUE)
return (status);
curwp->w_dotline = lineno;
return (TRUE);
}
int
markpara(int f, int n)
{
int i = 0;
if (n == 0)
return (TRUE);
clearmark(FFARG, 0);
if (findpara() == FALSE)
return (TRUE);
(void)do_gotoeop(FFRAND, n, &i);
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
(void)gotobop(FFRAND, i);
return (TRUE);
}
int
transposepara(int f, int n)
{
int i = 0, status;
char flg;
if (n == 0)
return (TRUE);
undo_boundary_enable(FFRAND, 0);
gotobop(FFRAND, 1);
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
(void)gotoeop(FFRAND, 1);
flg = curbp->b_flag;
kdelete();
if ((status = killregion(FFRAND, 1)) != TRUE)
return (status);
if (do_gotoeop(FFRAND, n, &i) == FALSE) {
ewprintf("Cannot transpose paragraph, end of buffer reached.");
(void)gotobop(FFRAND, i);
(void)yank(FFRAND, 1);
curbp->b_flag = flg;
return (FALSE);
}
(void)yank(FFRAND, 1);
undo_boundary_enable(FFRAND, 1);
return (TRUE);
}
int
findpara(void)
{
int col, nospace = 0;
do {
curwp->w_doto = 0;
col = 0;
while (col < llength(curwp->w_dotp)) {
if (!isspace(lgetc(curwp->w_dotp, col)))
nospace = 1;
col++;
}
if (nospace)
break;
if (lforw(curwp->w_dotp) == curbp->b_headp)
return (FALSE);
curwp->w_dotp = lforw(curwp->w_dotp);
curwp->w_dotline++;
} while (1);
return (TRUE);
}
int
fillword(int f, int n)
{
char c;
int col, i, nce;
for (i = col = 0; col <= fillcol; ++i, ++col) {
if (i == curwp->w_doto)
return selfinsert(f, n);
c = lgetc(curwp->w_dotp, i);
if (c == '\t')
col = ntabstop(col, curwp->w_bufp->b_tabw);
else if (ISCTRL(c) != FALSE)
++col;
}
if (curwp->w_doto != llength(curwp->w_dotp)) {
(void)selfinsert(f, n);
nce = llength(curwp->w_dotp) - curwp->w_doto;
} else
nce = 0;
curwp->w_doto = i;
if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
do {
(void)backchar(FFRAND, 1);
} while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' &&
c != '\t' && curwp->w_doto > 0);
if (curwp->w_doto == 0)
do {
(void)forwchar(FFRAND, 1);
} while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' &&
c != '\t' && curwp->w_doto < llength(curwp->w_dotp));
(void)delwhite(FFRAND, 1);
(void)lnewline();
i = llength(curwp->w_dotp) - nce;
curwp->w_doto = i > 0 ? i : 0;
curwp->w_rflag |= WFMOVE;
if (nce == 0 && curwp->w_doto != 0)
return (fillword(f, n));
return (TRUE);
}
int
setfillcol(int f, int n)
{
char buf[32], *rep;
const char *es;
int nfill;
if ((f & FFARG) != 0) {
fillcol = n;
} else {
if ((rep = eread("Set fill-column: ", buf, sizeof(buf),
EFNEW | EFCR)) == NULL)
return (ABORT);
else if (rep[0] == '\0')
return (FALSE);
nfill = strtonum(rep, 0, INT_MAX, &es);
if (es != NULL) {
dobeep();
ewprintf("Invalid fill column: %s", rep);
return (FALSE);
}
fillcol = nfill;
ewprintf("Fill column set to %d", fillcol);
}
return (TRUE);
}
int
sentencespace(int f, int n)
{
if (f & FFARG)
dblspace = n > 1;
else
dblspace = !dblspace;
return (TRUE);
}