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:
parent
13dde2bda4
commit
05417a2444
@ -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
2
TODO
@ -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]
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 "?????";
|
||||
}
|
||||
|
28
src/nano.c
28
src/nano.c
@ -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();
|
||||
}
|
||||
|
@ -490,6 +490,7 @@ enum
|
||||
BOLD_TEXT,
|
||||
QUIET,
|
||||
UNDOABLE,
|
||||
SOFTWRAP,
|
||||
};
|
||||
|
||||
/* Flags for which menus in which a given function should be present */
|
||||
|
@ -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);
|
||||
|
@ -92,6 +92,7 @@ static const rcoption rcopts[] = {
|
||||
{"undo", 0},
|
||||
{"whitespace", 0},
|
||||
{"wordbounds", WORD_BOUNDS},
|
||||
{"softwrap", SOFTWRAP},
|
||||
#endif
|
||||
{NULL, 0}
|
||||
};
|
||||
|
10
src/text.c
10
src/text.c
@ -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;
|
||||
|
84
src/winio.c
84
src/winio.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user