1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-07-01 05:55:24 +00:00

Rework previous-paragraph, next-paragraph, fill-paragraph, justify-paragraph.

This commit is contained in:
Renaud 2021-07-16 12:24:13 +08:00
parent 8a28c7ae77
commit d7649cf554
2 changed files with 69 additions and 55 deletions

View File

@ -98,9 +98,9 @@ tags: ${SRC}
$(E) " CC " $@ $(E) " CC " $@
$(Q) ${CC} ${CFLAGS} ${DEFINES} -c $*.c $(Q) ${CC} ${CFLAGS} ${DEFINES} -c $*.c
depend.mak: $(SRCS) depend.mak: $(wildcard *.h)
$(E) " DEPEND" $(E) " DEPEND"
$(Q) $(CC) $(DEFINES) -MM $+ > depend.mak $(Q) $(CC) $(DEFINES) -MM $(SRCS) > depend.mak
include depend.mak include depend.mak

120
word.c
View File

@ -11,6 +11,8 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memcpy */
#include "basic.h" #include "basic.h"
#include "buffer.h" #include "buffer.h"
@ -22,7 +24,7 @@
#include "region.h" #include "region.h"
#include "window.h" #include "window.h"
#define MAXWORDLEN (2 * NSTRING) #define ALLOCSZ 32
#define TAB 0x09 /* a tab character */ #define TAB 0x09 /* a tab character */
#if PKCODE #if PKCODE
@ -354,16 +356,15 @@ static int inword( void) {
*/ */
int fillpara(int f, int n) int fillpara(int f, int n)
{ {
unicode_t c; /* current char during scan */ unicode_t c; /* current char during scan */
unicode_t wbuf[ MAXWORDLEN] ; /* buffer for current word */ unicode_t *wbuf ; /* buffer for current word */
int wbufsize ;
int wordlen; /* length of current word */ int wordlen; /* length of current word */
int clength; /* position on line during fill */ int clength; /* position on line during fill */
int i; /* index during word copy */ int i; /* index during word copy */
int newlength; /* tentative new line length */
int eopflag; /* Are we at the End-Of-Paragraph? */ int eopflag; /* Are we at the End-Of-Paragraph? */
int firstflag; /* first word? (needs no space) */ int firstflag; /* first word? (needs no space) */
struct line *eopline; /* pointer to line just past EOP */ struct line *eopline; /* pointer to line just past EOP */
int dotflag; /* was the last char a period? */
if (curbp->b_mode & MDVIEW) /* don't allow this command if */ if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */ return rdonly(); /* we are in read only mode */
@ -375,6 +376,11 @@ int fillpara(int f, int n)
justflag = FALSE; justflag = FALSE;
#endif #endif
wbufsize = ALLOCSZ ;
wbuf = malloc( ALLOCSZ * sizeof *wbuf) ;
if( NULL == wbuf)
return FALSE ;
/* record the pointer to the line just past the EOP */ /* record the pointer to the line just past the EOP */
gotoeop(FALSE, 1); gotoeop(FALSE, 1);
eopline = lforw(curwp->w_dotp); eopline = lforw(curwp->w_dotp);
@ -383,11 +389,8 @@ int fillpara(int f, int n)
gotobop(FALSE, 1); gotobop(FALSE, 1);
/* initialize various info */ /* initialize various info */
clength = curwp->w_doto; clength = getccol( FALSE) ;
if (clength && curwp->w_dotp->l_text[0] == TAB)
clength = 8;
wordlen = 0; wordlen = 0;
dotflag = FALSE;
/* scan through lines, filling words */ /* scan through lines, filling words */
firstflag = TRUE; firstflag = TRUE;
@ -408,14 +411,23 @@ int fillpara(int f, int n)
/* if not a separator, just add it in */ /* if not a separator, just add it in */
if (c != ' ' && c != '\t') { if (c != ' ' && c != '\t') {
dotflag = (c == '.'); /* was it a dot */ if (wordlen < wbufsize)
if (wordlen < MAXWORDLEN)
wbuf[wordlen++] = c; wbuf[wordlen++] = c;
else {
/* overflow */
unicode_t *newptr ;
newptr = realloc( wbuf, (wbufsize + ALLOCSZ) * sizeof *wbuf) ;
if( newptr != NULL) {
wbuf = newptr ;
wbufsize += ALLOCSZ ;
wbuf[ wordlen++] = c ;
} /* else the word is truncated silently */
}
} else if (wordlen) { } else if (wordlen) {
/* at a word break with a word waiting */ /* at a word break with a word waiting */
/* calculate tentative new length with word added */ /* calculate tentative new length with word added */
newlength = clength + 1 + wordlen; if( fillcol > clength + 1 + wordlen) {
if (newlength <= fillcol) {
/* add word to current line */ /* add word to current line */
if (!firstflag) { if (!firstflag) {
linsert(1, ' '); /* the space */ linsert(1, ' '); /* the space */
@ -430,10 +442,12 @@ int fillpara(int f, int n)
/* and add the word in in either case */ /* and add the word in in either case */
for (i = 0; i < wordlen; i++) { for (i = 0; i < wordlen; i++) {
linsert(1, wbuf[i]); c = wbuf[ i] ;
linsert(1, c);
++clength; ++clength;
} }
if (dotflag) {
if( c == '.') { /* was the last char a period? */
linsert(1, ' '); linsert(1, ' ');
++clength; ++clength;
} }
@ -442,6 +456,7 @@ int fillpara(int f, int n)
} }
/* and add a last newline for the end of our new paragraph */ /* and add a last newline for the end of our new paragraph */
lnewline(); lnewline();
free( wbuf) ;
return TRUE; return TRUE;
} }
@ -453,12 +468,12 @@ int fillpara(int f, int n)
*/ */
int justpara(int f, int n) int justpara(int f, int n)
{ {
unicode_t c; /* current char durring scan */ unicode_t c; /* current char during scan */
unicode_t wbuf[ MAXWORDLEN] ; /* buffer for current word */ unicode_t *wbuf ; /* buffer for current word */
int wbufsize ;
int wordlen; /* length of current word */ int wordlen; /* length of current word */
int clength; /* position on line during fill */ int clength; /* position on line during fill */
int i; /* index during word copy */ int i; /* index during word copy */
int newlength; /* tentative new line length */
int eopflag; /* Are we at the End-Of-Paragraph? */ int eopflag; /* Are we at the End-Of-Paragraph? */
int firstflag; /* first word? (needs no space) */ int firstflag; /* first word? (needs no space) */
struct line *eopline; /* pointer to line just past EOP */ struct line *eopline; /* pointer to line just past EOP */
@ -471,13 +486,17 @@ int justpara(int f, int n)
return FALSE; return FALSE;
} }
justflag = TRUE; justflag = TRUE;
leftmarg = curwp->w_doto; leftmarg = getccol( FALSE) ;
if (leftmarg + 10 > fillcol) { if (leftmarg + 10 > fillcol) {
leftmarg = 0;
mloutstr( "Column too narrow") ; mloutstr( "Column too narrow") ;
return FALSE; return FALSE;
} }
wbufsize = ALLOCSZ ;
wbuf = malloc( ALLOCSZ * sizeof *wbuf) ;
if( NULL == wbuf)
return FALSE ;
/* record the pointer to the line just past the EOP */ /* record the pointer to the line just past the EOP */
gotoeop(FALSE, 1); gotoeop(FALSE, 1);
eopline = lforw(curwp->w_dotp); eopline = lforw(curwp->w_dotp);
@ -487,11 +506,9 @@ int justpara(int f, int n)
/* initialize various info */ /* initialize various info */
if (leftmarg < llength(curwp->w_dotp)) if (leftmarg < llength(curwp->w_dotp))
curwp->w_doto = leftmarg; setccol( leftmarg) ;
clength = curwp->w_doto; clength = getccol( FALSE) ;
if (clength && curwp->w_dotp->l_text[0] == TAB)
clength = 8;
wordlen = 0; wordlen = 0;
@ -514,13 +531,23 @@ int justpara(int f, int n)
/* if not a separator, just add it in */ /* if not a separator, just add it in */
if (c != ' ' && c != '\t') { if (c != ' ' && c != '\t') {
if (wordlen < MAXWORDLEN) if (wordlen < wbufsize)
wbuf[wordlen++] = c; wbuf[wordlen++] = c;
else {
/* overflow */
unicode_t *newptr ;
newptr = realloc( wbuf, ( wbufsize + ALLOCSZ) * sizeof *wbuf) ;
if( newptr != NULL) {
wbuf = newptr ;
wbufsize += ALLOCSZ ;
wbuf[ wordlen++] = c ;
} /* else the word is truncated silently */
}
} else if (wordlen) { } else if (wordlen) {
/* at a word break with a word waiting */ /* at a word break with a word waiting */
/* calculate tentative new length with word added */ /* calculate tentative new length with word added */
newlength = clength + 1 + wordlen; if( fillcol > clength + 1 + wordlen) {
if (newlength <= fillcol) {
/* add word to current line */ /* add word to current line */
if (!firstflag) { if (!firstflag) {
linsert(1, ' '); /* the space */ linsert(1, ' '); /* the space */
@ -547,12 +574,10 @@ int justpara(int f, int n)
lnewline(); lnewline();
forwword(FALSE, 1); forwword(FALSE, 1);
if (llength(curwp->w_dotp) > leftmarg) setccol( leftmarg) ;
curwp->w_doto = leftmarg;
else
curwp->w_doto = llength(curwp->w_dotp);
justflag = FALSE; justflag = FALSE;
free( wbuf) ;
return TRUE; return TRUE;
} }
#endif #endif
@ -668,17 +693,14 @@ int wordcount(int f, int n)
*/ */
int gotobop(int f, int n) int gotobop(int f, int n)
{ {
int suc; /* success of last backchar */
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotoeop(f, -n); return gotoeop(f, -n);
while (n-- > 0) { /* for each one asked for */ while (n-- > 0) { /* for each one asked for */
/* first scan back until we are in a word */ /* first scan back until we are in a word */
suc = backchar(FALSE, 1); while( backchar( FALSE, 1) && !inword()) ;
while (!inword() && suc)
suc = backchar(FALSE, 1);
curwp->w_doto = 0; /* and go to the B-O-Line */ curwp->w_doto = 0; /* and go to the B-O-Line */
/* and scan back until we hit a <NL><NL> or <NL><TAB> /* and scan back until we hit a <NL><NL> or <NL><TAB>
@ -698,16 +720,14 @@ int gotobop(int f, int n)
break; break;
/* and then forward until we are in a word */ /* and then forward until we are in a word */
suc = forwchar(FALSE, 1); while( !inword() && forwchar( FALSE, 1)) ;
while (suc && !inword())
suc = forwchar(FALSE, 1);
} }
curwp->w_flag |= WFMOVE; /* force screen update */ curwp->w_flag |= WFMOVE; /* force screen update */
return TRUE; return TRUE;
} }
/* /*
* Go forword to the end of the current paragraph * Go forward to the end of the current paragraph
* here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE> * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
* combination to delimit the beginning of a paragraph * combination to delimit the beginning of a paragraph
* *
@ -715,21 +735,17 @@ int gotobop(int f, int n)
*/ */
int gotoeop(int f, int n) int gotoeop(int f, int n)
{ {
int suc; /* success of last backchar */
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotobop(f, -n); return gotobop(f, -n);
while (n-- > 0) { /* for each one asked for */ while (n-- > 0) { /* for each one asked for */
/* first scan forward until we are in a word */ /* first scan forward until we are in a word */
suc = forwchar(FALSE, 1); while( !inword() && forwchar( FALSE, 1)) ;
while (!inword() && suc) curwp->w_doto = 0 ; /* and go to the B-O-Line */
suc = forwchar(FALSE, 1); if( curwp->w_dotp != curbp->b_linep) /* of next line if not at EOF */
curwp->w_doto = 0; /* and go to the B-O-Line */ curwp->w_dotp = lforw( curwp->w_dotp) ;
if (suc) /* of next line if not at EOF */
curwp->w_dotp = lforw(curwp->w_dotp);
/* and scan forword until we hit a <NL><NL> or <NL><TAB> /* and scan forward until we hit a <NL><NL> or <NL><TAB>
or a <NL><SPACE> */ or a <NL><SPACE> */
while (curwp->w_dotp != curbp->b_linep) { while (curwp->w_dotp != curbp->b_linep) {
if (llength(curwp->w_dotp) != 0 && if (llength(curwp->w_dotp) != 0 &&
@ -747,10 +763,8 @@ int gotoeop(int f, int n)
} }
/* and then backward until we are in a word */ /* and then backward until we are in a word */
suc = backchar(FALSE, 1); while( backchar( FALSE, 1) && !inword()) ;
while (suc && !inword()) {
suc = backchar(FALSE, 1);
}
curwp->w_doto = llength(curwp->w_dotp); /* and to the EOL */ curwp->w_doto = llength(curwp->w_dotp); /* and to the EOL */
} }
curwp->w_flag |= WFMOVE; /* force screen update */ curwp->w_flag |= WFMOVE; /* force screen update */