]> git.wh0rd.org Git - nano.git/commitdiff
2009-08-17 Chris Allegretta <chrisa@asty.org>
authorChris Allegretta <chrisa@asty.org>
Mon, 17 Aug 2009 07:52:10 +0000 (07:52 +0000)
committerChris Allegretta <chrisa@asty.org>
Mon, 17 Aug 2009 07:52:10 +0000 (07:52 +0000)
        * 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

ChangeLog
TODO
doc/man/nano.1
doc/man/nanorc.5
src/global.c
src/nano.c
src/nano.h
src/proto.h
src/rcfile.c
src/text.c
src/winio.c

index 397b7f1395579099c09021768a9fe450fdd0fab4..85925009a9a100271d52138ff1d351081c01c4de 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/TODO b/TODO
index 9fce6e5cc149ef976a8a68d8679e60754357e6bd..6780d61ab7d92012a0c96296b246a6c9bb435cc4 100644 (file)
--- a/TODO
+++ b/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]
index 9af89978034e133b3042d6d575b4ae308ed61a47..e9954e952ef6d5da28c3cef2f25a903161183e42 100644 (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.
 
index 73e7d9721fb71376a0db142dddd4e71196aa537c..4d56d7ff55df582a5d37d32ea9ff05a0cb676af0 100644 (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.
index f6826d7f468fb6d20aa91dbee6f7ebed2d732c2d..dbd42091103a2367a2f980aa89d26eeed3804961 100644 (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 "?????";
     }
index 7ef21b172362c29555c45cb5564aef5ed42d72d8..9d1e011f5d83f3555c65a0e14c1d44f301a4af1a 100644 (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();
        }
index 9400fe058a6026a5de76c88a0f89445fcce9cf74..e9996a4dd21a34b94e0b1dfd05e42763ab84acb4 100644 (file)
@@ -490,6 +490,7 @@ enum
     BOLD_TEXT,
     QUIET,
     UNDOABLE,
+    SOFTWRAP,
 };
 
 /* Flags for which menus in which a given function should be present */
index 3e83f1bacf89da32a5451a43a5ec900aabed54a7..19b3881dda21f6df28ec533178164f1c1611953b 100644 (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);
index 60a9f3dddb2260dc26b2bbca19b28ca0ad982fc6..decae7863ed97cd9a9fe15b4be405492130e520d 100644 (file)
@@ -92,6 +92,7 @@ static const rcoption rcopts[] = {
     {"undo", 0},
     {"whitespace", 0},
     {"wordbounds", WORD_BOUNDS},
+    {"softwrap", SOFTWRAP},
 #endif
     {NULL, 0}
 };
index a3683f4048c1c29a929e7f781aefa75a93db6637..51ad00b23fb75474d52d3477d30f94382afa2015 100644 (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;
index 759b69e6899d6e856caa502714d18ad994b2c027..6a9be893d11edbdee25b15f1fe21d640898ed1b9 100644 (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;
     }