add experimental new do_wrap() and check_wrap() to imitate pico a little closer.

Please try this and let me know if it doesn't work!


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@9 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
Adam Rogoyski 2000-06-07 03:56:54 +00:00
parent 57474c34b3
commit 77f36de7e9

306
nano.c
View File

@ -32,6 +32,7 @@
#include <ctype.h> #include <ctype.h>
#include <locale.h> #include <locale.h>
#include <limits.h> #include <limits.h>
#include <assert.h>
#include "config.h" #include "config.h"
#include "proto.h" #include "proto.h"
@ -850,8 +851,8 @@ void do_char(char ch)
current->data[current_x] = ch; current->data[current_x] = ch;
do_right(); do_right();
if (!ISSET(NO_WRAP)) if (!ISSET(NO_WRAP) && (ch != '\t'))
check_wrap(current); check_wrap(current, ch);
set_modified(); set_modified();
check_statblank(); check_statblank();
UNSET(KEEP_CUTBUFFER); UNSET(KEEP_CUTBUFFER);
@ -965,98 +966,259 @@ void do_next_word(void)
} }
/* Actually wrap a line, called by check_wrap() */ void do_wrap(filestruct *inptr, char input_char)
void do_wrap(filestruct * inptr)
{ {
int i, j, chop; int i = 0; /* Index into ->data for line.*/
char *tmp, *foo; int i_tabs = 0; /* Screen position of ->data[i]. */
int last_word_end = -1; /* Location of end of last word found. */
int current_word_start = -1; /* Location of start of current word. */
int current_word_start_t = -1; /* Location of start of current word screen position. */
int current_word_end = -1; /* Location of end of current word */
int current_word_end_t = -1; /* Location of end of current word screen position. */
int len = strlen(inptr->data);
i = actual_x(inptr, fill); int down = 0;
int right = 0;
struct filestruct *temp = NULL;
while (inptr->data[i] != ' ' && inptr->data[i] != '\t' && i != 0) assert (strlenpt(inptr->data) >= fill);
i--;
if (i == 0) for (i = 0, i_tabs; i < len; i++, i_tabs++) {
return; if (!isspace(inptr->data[i])) {
last_word_end = current_word_end;
while ((inptr->data[i] == ' ' || inptr->data[i] == '\t') && i != 0) current_word_start = i;
i--; current_word_start_t = i_tabs;
if (i == 0) while (!isspace(inptr->data[i]) && inptr->data[i]) {
return; i++;
i_tabs++;
if (inptr->data[i] < 32)
i_tabs++;
}
/* NB: This sucks */ if (inptr->data[i]) {
if (inptr->data[i] != 0) current_word_end = i;
i++; current_word_end_t = i_tabs;
if (inptr->data[i] != 0) }
i++; else {
current_word_end = i - 1;
chop = i; current_word_end_t = i_tabs - 1;
while ((inptr->data[i] == ' ' || inptr->data[i] == '\t') && }
inptr->data[i] != 0)
i++;
if (inptr->data[i] == 0)
return;
if (ISSET(SAMELINEWRAP)) {
tmp = &current->data[i];
foo = nmalloc(strlen(tmp) + strlen(current->next->data) + 1);
strcpy(foo, tmp);
strcpy(&foo[strlen(tmp)], current->next->data);
free(current->next->data);
current->next->data = foo;
*tmp = 0;
current->data[chop] = 0;
align(&current->data);
if (current_x >= i) {
current_x = current_x - i;
current = current->next;
} }
if (current->next == NULL) {
current->next = make_new_node(current);
current->next->data = nmalloc(1);
current->next->data[0] = 0;
filebot = current->next;
}
align(&current->next->data);
edit_refresh(); if (inptr->data[i] == NANO_CONTROL_I) {
} else { if (i_tabs % 8 != 0);
i_tabs += 8 - (i_tabs % 8);
}
j = current_x; if (current_word_end_t >= fill)
current_x = i; break;
do_enter(current);
current->prev->data[chop] = 0;
align(&current->prev->data);
if (j > i) {
current_x = j - i;
UNSET(SAMELINEWRAP);
} else {
current_x = j;
current = current->prev;
SET(SAMELINEWRAP);
}
} }
assert (current_word_end_t >= fill);
/* There are 4 cases of what the line could look like.
* 1) only one word on the line before wrap point.
* a) cursor is on word or before word at wrap point.
* - word starts new line.
* - keep white space on original line up to the cursor.
* *) cursor is after word at wrap point
* - either it's all white space after word, and this routine isn't called.
* - or we are actually in case 2 (2 words).
* 2) Two or more words on the line before wrap point.
* a) cursor is at a word before wrap point
* - word at wrap point starts a new line.
* - white space at end of original line is cleared.
* b) cursor is at the word at the wrap point.
* - word at wrap point starts a new line.
* 1. pressed a space.
* - white space on original line is kept to where cursor was.
* 2. pressed non space.
* - white space at end of original line is cleared.
* c) cursor is past the word at the wrap point.
* - word at wrap point starts a new line.
* 1. pressed a space.
* - white space on original line is kept to where wrap point was.
* 2. pressed a non space.
* - white space at end of original line is cleared
*/
temp = nmalloc (sizeof (filestruct));
/* Category 1a: one word on the line */
if (last_word_end == -1) {
temp->data = nmalloc(strlen(&inptr->data[current_word_start]) + 1);
strcpy(temp->data, &inptr->data[current_word_start]);
/* Inside word, remove it from original, and move cursor to right spot. */
if (current_x >= current_word_start) {
right = current_x - current_word_start;
current_x = 0;
down = 1;
}
inptr->data = nrealloc(inptr->data, current_x + 1);
inptr->data[current_x] = 0;
}
/* Category 2: two or more words on the line. */
else {
/* Case 2a: cursor before word at wrap point. */
if (current_x < current_word_start) {
temp->data = nmalloc(strlen(&inptr->data[current_word_start]) + 1);
strcpy(temp->data, &inptr->data[current_word_start]);
i = current_word_start - 1;
while (isspace(inptr->data[i])) {
i--;
assert (i >= 0);
}
inptr->data = nrealloc(inptr->data, i + 2);
inptr->data[i + 1] = 0;
}
/* Case 2b: cursor at word at wrap point. */
else if ((current_x >= current_word_start)
&& (current_x <= (current_word_end + 1))) {
temp->data = nmalloc(strlen(&inptr->data[current_word_start]) + 1);
strcpy(temp->data, &inptr->data[current_word_start]);
down = 1;
right = current_x - current_word_start;
i = current_word_start - 1;
if (isspace(input_char)) {
current_x = current_word_start;
inptr->data = nrealloc(inptr->data, current_word_start + 1);
inptr->data[current_word_start] = 0;
}
else {
while (isspace(inptr->data[i])) {
i--;
assert (i >= 0);
}
inptr->data = nrealloc(inptr->data, i + 2);
inptr->data[i + 1] = 0;
}
}
/* Case 2c: cursor past word at wrap point. */
else {
temp->data = nmalloc(strlen(&inptr->data[current_word_start]) + 1);
strcpy(temp->data, &inptr->data[current_word_start]);
down = 1;
right = current_x - current_word_start;
current_x = current_word_start;
i = current_word_start - 1;
if (isspace(input_char)) {
inptr->data = nrealloc(inptr->data, current_word_start + 1);
inptr->data[current_word_start] = 0;
}
else {
while (isspace(inptr->data[i])) {
i--;
assert (i >= 0);
}
inptr->data = nrealloc(inptr->data, i + 2);
inptr->data[i + 1] = 0;
}
}
}
/* We pre-pend wrapped part to next line. */
if (ISSET(SAMELINEWRAP)) {
/* Plus one for the space which concatenates the two lines together plus 1 for \0. */
char *p = nmalloc(strlen(temp->data) + strlen(inptr->next->data) + 2);
strcpy (p, temp->data);
strcat (p, " ");
strcat (p, inptr->next->data);
free (inptr->next->data);
inptr->next->data = p;
free (temp->data);
free (temp);
}
/* Else we start a new line. */
else {
temp->prev = inptr;
temp->next = inptr->next;
if (inptr->next)
inptr->next->prev = temp;
inptr->next = temp;
if (!temp->next)
filebot = temp;
SET(SAMELINEWRAP);
}
totlines++;
totsize++;
renumber (inptr);
edit_update(current);
/* Move the cursor to the new line if appropriate. */
if (down) {
do_right();
}
/* Move the cursor to the correct spot in the line if appropriate. */
while (right--) {
do_right();
}
edit_update(current);
reset_cursor();
edit_refresh();
} }
/* Check to see if we've just caused the line to wrap to a new line */ /* Check to see if we've just caused the line to wrap to a new line */
void check_wrap(filestruct * inptr) void check_wrap(filestruct * inptr, char ch)
{ {
int len = strlenpt(inptr->data);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("check_wrap called with inptr->data=\"%s\"\n"), fprintf(stderr, _("check_wrap called with inptr->data=\"%s\"\n"),
inptr->data); inptr->data);
#endif #endif
if ((int) strlenpt(inptr->data) <= fill) if (len <= fill)
return; return;
else else {
do_wrap(inptr); int i = actual_x(inptr, fill);
/* Do not wrap if there are no words on or after wrap point. */
/* First check to see if we typed space and passed a word. */
if (isspace(ch) && !isspace(inptr->data[i - 1]))
do_wrap(inptr, ch);
else {
while (isspace(inptr->data[i]) && inptr->data[i])
i++;
if (!inptr->data[i])
return;
do_wrap(inptr, ch);
}
}
} }
/* Stuff we do when we abort from programs and want to clean up the /* Stuff we do when we abort from programs and want to clean up the