2009-08-17 Chris Allegretta <chrisa@asty.org>

* Initial soft line wrapping implementation.  Command line flags
          -$ or --softwrap.
        * nano.c, text.c: Clean up some fprintf warnings in debug mode due to printing
          a size_t without using the zd specifier.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4402 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
Chris Allegretta 2009-08-17 07:52:10 +00:00
parent 13dde2bda4
commit 05417a2444
11 changed files with 117 additions and 32 deletions

View File

@ -1,3 +1,8 @@
2009-08-17 Chris Allegretta <chrisa@asty.org>
* Initial soft line wrapping implementation. Command line flags
-$ or --softwrap.
* nano.c, text.c: Clean up some fprintf warnings in debug mode due to printing
a size_t without using the zd specifier.
2009-08-13 Chris Allegretta <chrisa@asty.org>
* New global flag implementation courtesy of Adam Wysocki <gophi@arcabit.pl>, allows
previous undo flag to be implemented consistent with other flags.

2
TODO
View File

@ -24,7 +24,6 @@ For the future (no targeted version, catch-all)
allow movement between them with a single keystroke? (we're running
out of keystrokes)
- Allow searching for and replacing newlines.
- Allow soft wrapping as well as hard wrapping?
- Fix handling of bad/incomplete UTF-8 sequences to display one Unicode
FFFD (Replacement Character) per sequence instead of one per byte.
@ -48,6 +47,7 @@ For version 2.2:
- Allow nano to work like a pager (read from stdin) [DONE]
- Allow color syntaxes to be selected based on more than just filename
extension, [DONE]
- Allow soft wrapping as well as hard wrapping? [DONE]
For version 2.0:
- UTF-8 support. [DONE]

View File

@ -205,6 +205,13 @@ Disable help screen at bottom of editor.
.B \-z (\-\-suspend)
Enable suspend ability.
.TP
.B \-$ (\-\-softwrap)
Enable 'soft wrapping'. Nano will attempt to display lines the entire
contents of a line, even if it is longer than the screen width.
Since '$' normally refers to a variable in the Unix shell, you should
specify this option last when using other options (e.g. 'nano -wS$')
or pass it separately (e.g. 'nano -wS -$').
.TP
.B \-a, \-b, \-e, \-f, \-g, \-j
Ignored, for compatibility with Pico.

View File

@ -185,6 +185,9 @@ line.
.B set/unset smooth
Use smooth scrolling by default.
.TP
.B set/unset softwrap
Enable soft line wrapping for easier viewing of very long lones.
.TP
.B set speller "\fIspellprog\fP"
Use spelling checker \fIspellprog\fP instead of the built-in one, which
calls \fIspell\fP.
@ -208,6 +211,9 @@ Enable experimental generic-purpose undo code.
.B set/unset view
Disallow file modification.
.TP
.B set/unset softwrap
Enable soft line wrapping for easier viewing of very long lones.
.TP
.B set whitespace "\fIstring\fP"
Set the two characters used to display the first characters of tabs and
spaces. They must be single-column characters.

View File

@ -1164,6 +1164,7 @@ void shortcut_init(bool unjustify)
add_to_sclist(MMAIN, "M-M", DO_TOGGLE, USE_MOUSE, TRUE);
add_to_sclist(MMAIN, "M-N", DO_TOGGLE, NO_CONVERT, TRUE);
add_to_sclist(MMAIN, "M-Z", DO_TOGGLE, SUSPEND, TRUE);
add_to_sclist(MMAIN, "M-$", DO_TOGGLE, SOFTWRAP, TRUE);
#endif
add_to_sclist(MGOTOLINE, "^T", GOTOTEXT_MSG, 0, FALSE);
add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", NEW_BUFFER_MSG, 0, FALSE);
@ -1376,6 +1377,8 @@ char *flagtostr(int flag)
return N_("No conversion from DOS/Mac format");
case SUSPEND:
return N_("Suspension");
case SOFTWRAP:
return N_("Soft line wrapping");
default:
return "?????";
}

View File

@ -901,6 +901,7 @@ void usage(void)
#endif
print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
print_opt("-z", "--suspend", N_("Enable suspension"));
print_opt("-$", "--softwrap", N_("Enable soft line wrapping"));
/* This is a special case. */
print_opt("-a, -b, -e,", "", NULL);
@ -1333,6 +1334,9 @@ void do_toggle(int flag)
edit_refresh();
break;
#endif
case SOFTWRAP:
total_refresh();
break;
}
enabled = ISSET(flag);
@ -1733,7 +1737,7 @@ void precalc_multicolorinfo(void)
#ifdef DEBUG
fprintf(stderr, "working on lineno %d\n", fileptr->lineno);
fprintf(stderr, "working on lineno %zd\n", fileptr->lineno);
#endif
alloc_multidata_if_needed(fileptr);
@ -1766,7 +1770,7 @@ void precalc_multicolorinfo(void)
for (endptr = fileptr->next; endptr != NULL; endptr = endptr->next) {
#ifdef DEBUG
fprintf(stderr, "advancing to line %d to find end...\n", endptr->lineno);
fprintf(stderr, "advancing to line %zd to find end...\n", endptr->lineno);
#endif
/* Check for keyboard input again */
if ((cur_check = time(NULL)) - last_check > 1) {
@ -1794,18 +1798,18 @@ void precalc_multicolorinfo(void)
lines in between and the ends properly */
fileptr->multidata[tmpcolor->id] |= CENDAFTER;
#ifdef DEBUG
fprintf(stderr, "marking line %d as CENDAFTER\n", fileptr->lineno);
fprintf(stderr, "marking line %zd as CENDAFTER\n", fileptr->lineno);
#endif
for (fileptr = fileptr->next; fileptr != endptr; fileptr = fileptr->next) {
alloc_multidata_if_needed(fileptr);
fileptr->multidata[tmpcolor->id] = CWHOLELINE;
#ifdef DEBUG
fprintf(stderr, "marking intermediary line %d as CWHOLELINE\n", fileptr->lineno);
fprintf(stderr, "marking intermediary line %zd as CWHOLELINE\n", fileptr->lineno);
#endif
}
alloc_multidata_if_needed(endptr);
#ifdef DEBUG
fprintf(stderr, "marking line %d as BEGINBEFORE\n", fileptr->lineno);
fprintf(stderr, "marking line %zd as BEGINBEFORE\n", fileptr->lineno);
#endif
endptr->multidata[tmpcolor->id] |= CBEGINBEFORE;
/* We should be able to skip all the way to the line of the match.
@ -1813,12 +1817,12 @@ void precalc_multicolorinfo(void)
fileptr = endptr;
startx = endmatch.rm_eo;
#ifdef DEBUG
fprintf(stderr, "jumping to line %d pos %d to continue\n", endptr->lineno, startx);
fprintf(stderr, "jumping to line %zd pos %d to continue\n", endptr->lineno, startx);
#endif
}
if (nostart && startx == 0) {
#ifdef DEBUG
fprintf(stderr, "no start found on line %d, continuing\n", fileptr->lineno);
fprintf(stderr, "no start found on line %zd, continuing\n", fileptr->lineno);
#endif
fileptr->multidata[tmpcolor->id] = CNONE;
continue;
@ -2020,6 +2024,7 @@ int main(int argc, char **argv)
{"wordbounds", 0, NULL, 'W'},
{"autoindent", 0, NULL, 'i'},
{"cut", 0, NULL, 'k'},
{"softwrap", 0, NULL, '$'},
#endif
{NULL, 0, NULL, 0}
};
@ -2058,11 +2063,11 @@ int main(int argc, char **argv)
while ((optchr =
#ifdef HAVE_GETOPT_LONG
getopt_long(argc, argv,
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz",
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz$",
long_options, NULL)
#else
getopt(argc, argv,
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz")
"h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz$")
#endif
) != -1) {
switch (optchr) {
@ -2230,6 +2235,11 @@ int main(int argc, char **argv)
case 'z':
SET(SUSPEND);
break;
#ifndef NANO_TINY
case '$':
SET(SOFTWRAP);
break;
#endif
default:
usage();
}

View File

@ -490,6 +490,7 @@ enum
BOLD_TEXT,
QUIET,
UNDOABLE,
SOFTWRAP,
};
/* Flags for which menus in which a given function should be present */

View File

@ -765,7 +765,7 @@ void onekey(const char *keystroke, const char *desc, size_t len);
void reset_cursor(void);
void edit_draw(filestruct *fileptr, const char *converted, int
line, size_t start);
void update_line(filestruct *fileptr, size_t index);
int update_line(filestruct *fileptr, size_t index);
bool need_horizontal_update(size_t pww_save);
bool need_vertical_update(size_t pww_save);
void edit_scroll(scroll_dir direction, ssize_t nlines);

View File

@ -92,6 +92,7 @@ static const rcoption rcopts[] = {
{"undo", 0},
{"whitespace", 0},
{"wordbounds", WORD_BOUNDS},
{"softwrap", SOFTWRAP},
#endif
{NULL, 0}
};

View File

@ -409,7 +409,7 @@ void redo_cut(undo *u) {
for (c = u->cutbuffer, t = openfile->current; c->next != NULL && t->next != NULL; ) {
#ifdef DEBUG
fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data);
fprintf(stderr, "Advancing, lineno = %zd, data = \"%s\"\n", t->lineno, t->data);
#endif
c = c->next;
t = t->next;
@ -943,7 +943,7 @@ void add_undo(undo_type current_action)
}
#ifdef DEBUG
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d, type = %d\n",
fprintf(stderr, "fs->current->data = \"%s\", current_x = %zd, u->begin = %d, type = %d\n",
fs->current->data, fs->current_x, u->begin, current_action);
fprintf(stderr, "left add_undo...\n");
#endif
@ -966,10 +966,10 @@ void update_undo(undo_type action)
return;
#ifdef DEBUG
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %d",
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %zd",
action, fs->last_action, openfile->current->lineno);
if (fs->current_undo)
fprintf(stderr, "fs->current_undo->lineno = %d\n", fs->current_undo->lineno);
fprintf(stderr, "fs->current_undo->lineno = %zd\n", fs->current_undo->lineno);
else
fprintf(stderr, "\n");
#endif
@ -989,7 +989,7 @@ void update_undo(undo_type action)
switch (u->type) {
case ADD:
#ifdef DEBUG
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d\n",
fprintf(stderr, "fs->current->data = \"%s\", current_x = %zd, u->begin = %d\n",
fs->current->data, fs->current_x, u->begin);
#endif
len = strlen(u->strdata) + 2;

View File

@ -2426,6 +2426,7 @@ void onekey(const char *keystroke, const char *desc, size_t len)
* in the edit window at (current_y, current_x). */
void reset_cursor(void)
{
size_t xpt;
/* If we haven't opened any files yet, put the cursor in the top
* left corner of the edit window and get out. */
if (openfile == NULL) {
@ -2433,13 +2434,24 @@ void reset_cursor(void)
return;
}
openfile->current_y = openfile->current->lineno -
openfile->edittop->lineno;
if (openfile->current_y < editwinrows) {
size_t xpt = xplustabs();
xpt = xplustabs();
wmove(edit, openfile->current_y, xpt - get_page_start(xpt));
}
if (ISSET(SOFTWRAP)) {
openfile->current_y = 0;
filestruct *tmp;
for (tmp = openfile->edittop; tmp != openfile->current; tmp = tmp->next)
openfile->current_y += 1 + strlenpt(tmp->data) / COLS;
openfile->current_y += xplustabs() / COLS;
if (openfile->current_y < editwinrows)
wmove(edit, openfile->current_y, xpt % COLS);
} else {
openfile->current_y = openfile->current->lineno -
openfile->edittop->lineno;
if (openfile->current_y < editwinrows)
wmove(edit, openfile->current_y, xpt - get_page_start(xpt));
}
}
/* edit_draw() takes care of the job of actually painting a line into
@ -2813,19 +2825,35 @@ void edit_draw(filestruct *fileptr, const char *converted, int
/* Just update one line in the edit buffer. This is basically a wrapper
* for edit_draw(). The line will be displayed starting with
* fileptr->data[index]. Likely arguments are current_x or zero. */
void update_line(filestruct *fileptr, size_t index)
* fileptr->data[index]. Likely arguments are current_x or zero.
* Returns: Number of additiona lines consumed (needed for SOFTWRAP)
*/
int update_line(filestruct *fileptr, size_t index)
{
int line;
int line = 0;
int extralinesused = 0;
/* The line in the edit window that we want to update. */
char *converted;
/* fileptr->data converted to have tabs and control characters
* expanded. */
size_t page_start;
filestruct *tmp;
assert(fileptr != NULL);
line = fileptr->lineno - openfile->edittop->lineno;
if (ISSET(SOFTWRAP)) {
for (tmp = openfile->edittop; tmp != fileptr; tmp = tmp->next) {
line += 1 + (strlenpt(tmp->data) / COLS);
#ifdef DEBUG
fprintf(stderr, "update_line(): inside loop, line = %d\n", line);
#endif
}
} else
line = fileptr->lineno - openfile->edittop->lineno;
#ifdef DEBUG
fprintf(stderr, "update_line(): line = %d\n", line);
#endif
if (line < 0 || line >= editwinrows)
return;
@ -2835,7 +2863,10 @@ void update_line(filestruct *fileptr, size_t index)
/* Next, convert variables that index the line to their equivalent
* positions in the expanded line. */
index = strnlenpt(fileptr->data, index);
if (ISSET(SOFTWRAP))
index = 0;
else
index = strnlenpt(fileptr->data, index);
page_start = get_page_start(index);
/* Expand the line, replacing tabs with spaces, and control
@ -2846,10 +2877,31 @@ void update_line(filestruct *fileptr, size_t index)
edit_draw(fileptr, converted, line, page_start);
free(converted);
if (page_start > 0)
mvwaddch(edit, line, 0, '$');
if (strlenpt(fileptr->data) > page_start + COLS)
mvwaddch(edit, line, COLS - 1, '$');
if (!ISSET(SOFTWRAP)) {
if (page_start > 0)
mvwaddch(edit, line, 0, '$');
if (strlenpt(fileptr->data) > page_start + COLS)
mvwaddch(edit, line, COLS - 1, '$');
} else {
int full_length = strlenpt(fileptr->data);
for (index += COLS; index < full_length && line < editwinrows; index += COLS) {
line++;
#ifdef DEBUG
fprintf(stderr, "update_line(): Softwrap code, moving to %d\n", line);
#endif
blank_line(edit, line, 0, COLS);
/* Expand the line, replacing tabs with spaces, and control
* characters with their displayed forms. */
converted = display_string(fileptr->data, index, COLS, TRUE);
/* Paint the line. */
edit_draw(fileptr, converted, line, index);
free(converted);
extralinesused++;
}
}
return extralinesused;
}
/* Return TRUE if we need an update after moving horizontally, and FALSE
@ -3115,7 +3167,7 @@ void edit_refresh(void)
#endif
for (nlines = 0; nlines < editwinrows && foo != NULL; nlines++) {
update_line(foo, (foo == openfile->current) ?
nlines += update_line(foo, (foo == openfile->current) ?
openfile->current_x : 0);
foo = foo->next;
}