+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.
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.
- 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]
.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.
.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.
.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.
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);
return N_("No conversion from DOS/Mac format");
case SUSPEND:
return N_("Suspension");
+ case SOFTWRAP:
+ return N_("Soft line wrapping");
default:
return "?????";
}
#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);
edit_refresh();
break;
#endif
+ case SOFTWRAP:
+ total_refresh();
+ break;
}
enabled = ISSET(flag);
#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);
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) {
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.
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;
{"wordbounds", 0, NULL, 'W'},
{"autoindent", 0, NULL, 'i'},
{"cut", 0, NULL, 'k'},
+ {"softwrap", 0, NULL, '$'},
#endif
{NULL, 0, NULL, 0}
};
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) {
case 'z':
SET(SUSPEND);
break;
+#ifndef NANO_TINY
+ case '$':
+ SET(SOFTWRAP);
+ break;
+#endif
default:
usage();
}
BOLD_TEXT,
QUIET,
UNDOABLE,
+ SOFTWRAP,
};
/* Flags for which menus in which a given function should be present */
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);
{"undo", 0},
{"whitespace", 0},
{"wordbounds", WORD_BOUNDS},
+ {"softwrap", SOFTWRAP},
#endif
{NULL, 0}
};
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;
}
#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
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
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;
* 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) {
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
/* 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;
/* 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
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
#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;
}