Index: editwin.c
===================================================================
--- editwin.c	(revision 2da73482548054bd88ba616aea53da932fb3b2f4)
+++ editwin.c	(revision fc2677be1bd748f06e7854d251b7a413f6ea73d4)
@@ -59,4 +59,5 @@
 static char *oe_copy_buf(owl_editwin *e, char *buf, int len);
 static int oe_copy_region(owl_editwin *e);
+static int oe_display_column(owl_editwin *e);
 
 #define INCR 4096
@@ -587,41 +588,26 @@
 }
 
-#if 0 /*XXX*/
 /* linewrap the word just before the cursor.
  * returns 0 on success
  * returns -1 if we could not wrap.
  */
-static int _owl_editwin_linewrap_word(owl_editwin *e)
-{
-  int i;
-  char *ptr1, *start;
+static void _owl_editwin_linewrap_word(owl_editwin *e)
+{
+  oe_excursion x;
   gunichar c;
 
-  start = e->buff + e->lock;
-
-  ptr1 = e->buff + e->index;
-  ptr1 = g_utf8_find_prev_char(start, ptr1);
-
-  while (ptr1) {
-    c = g_utf8_get_char(ptr1);
-    if (owl_util_can_break_after(c)) {
-      if (c != ' ') {
-        i = ptr1 - e->buff;
-	oe_set_index(e, i);
-        _owl_editwin_insert_bytes(e, 1);
-        /* _owl_editwin_insert_bytes may move e->buff. */
-        ptr1 = e->buff + i;
-      }
-      *ptr1 = '\n';
-      return 0;
-    }
-    else if (c == '\n') {
-      return 0;
-    }
-    ptr1 = g_utf8_find_prev_char(start, ptr1);
-  }
-  return -1;
-}
-#endif
+  oe_save_excursion(e, &x);
+
+  while (owl_editwin_point_move(e, -1)) {
+    c = owl_editwin_get_char_at_point(e);
+    if (owl_util_can_break_after(c) || c == '\n') {
+      if (c != '\n')
+        owl_editwin_replace(e, c != ' ' ? 0 : 1, "\n");
+      break;
+    }
+  }
+
+  oe_restore_excursion(e, &x);
+}
 
 /* delete the character at the current point, following chars
@@ -1036,78 +1022,81 @@
 }
 
+static int oe_display_column(owl_editwin *e)
+{
+  oe_excursion x;
+  int lineindex;
+
+  oe_save_excursion(e, &x);
+  owl_editwin_move_to_beginning_of_line(e);
+  lineindex = e->index;
+  oe_restore_excursion(e, &x);
+  return oe_region_width(e, lineindex, e->index, 0);
+}
+
 void owl_editwin_fill_paragraph(owl_editwin *e)
 {
-#if 0 /* XXX */
   oe_excursion x;
-  int i, save;
-
-  /* save our starting point */
+  gunichar ch;
+  int sentence;
+
   oe_save_excursion(e, &x);
 
-  save = e->index;
-
-  /* scan back to the beginning of this paragraph */
-  for (i=save; i>=e->lock; i--) {
-    if ( (i<=e->lock) ||
-	 ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
-      oe_set_index(i + 1);
+  /* Mark the end of the paragraph */
+  owl_editwin_forward_paragraph(e);
+  /* Skip the trailing newline */
+  owl_editwin_point_move(e, -1);
+  owl_editwin_set_mark(e);
+
+  owl_editwin_backward_paragraph(e);
+
+  /* Don't mess with the leading newline */
+  if (owl_editwin_get_char_at_point(e) == '\n')
+    owl_editwin_point_move(e, 1);
+
+  /*
+   * First pass: Scan forward replacing all series of spaces with ' '
+   * (or nothing after CJK ideograms)
+   */
+  sentence = 0;
+  for(;e->index < e->mark; owl_editwin_point_move(e, 1)) {
+    /* bail if we hit a trailing dot on the buffer */
+    if (strcmp(e->buff + e->index, "\n.") == 0) {
+      owl_editwin_set_mark(e);
       break;
     }
-  }
-
-  /* main loop */
-  while (1) {
-    i = _owl_editwin_get_index_from_xy(e);
-
-    /* bail if we hit the end of the buffer */
-    if (i >= e->bufflen || e->buff[i] == '\0') break;
-
-    /* bail if we hit the end of the paragraph */
-    if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
-
-    /* bail if we hit a trailing dot on the buffer */
-    if (e->buff[i] == '\n' && e->buff[i+1] == '.'
-        && ((i+2) >= e->bufflen || e->buff[i+2] == '\0'))
-      break;
-
+
+    ch = owl_editwin_get_char_at_point(e);
+
+    if (owl_util_can_break_after(ch) || ch == '\n') {
+      if (g_unichar_isspace(ch)) {
+        owl_editwin_replace(e, 1, " ");
+      }
+
+      if (sentence)
+        owl_editwin_point_move(e, 1);
+
+      while(g_unichar_isspace(owl_editwin_get_char_at_point(e))
+            && e->index < e->mark) {
+        owl_editwin_delete_char(e);
+      }
+    }
+
+    if(ch == '.' || ch == '!' || ch == '?')
+      sentence = 1;
+    else
+      sentence = 0;
+  }
+
+  owl_editwin_backward_paragraph(e);
+
+  /* Now go through inserting newlines as needed */
+  while(e->index < e->mark) {
     /* if we've travelled too far, linewrap */
-    if ((e->buffx) >= e->fillcol) {
-      int len = e->bufflen;
+    if (oe_display_column(e) >= e->fillcol)
       _owl_editwin_linewrap_word(e);
-      /* we may have added a character. */
-      if (i < save) save += e->bufflen - len;
-      oe_set_index(i);
-    }
-
-    /* did we hit the end of a line too soon? */
-    /* asedeno: Here we replace a newline with a space. We may want to
-       consider removing the space if the characters to either side
-       are CJK ideograms.*/
-    i = _owl_editwin_get_index_from_xy(e);
-    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
-      /* ********* we need to make sure we don't pull in a word that's too long ***********/
-      e->buff[i]=' ';
-    }
-
-    /* fix spacing */
-    i = _owl_editwin_get_index_from_xy(e);
-    if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
-      if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
-	owl_editwin_key_right(e);
-      } else {
-	owl_editwin_delete_char(e);
-	/* if we did this ahead of the save point, adjust it. Changing
-           by one is fine here because we're only removing an ASCII
-           space. */
-	if (i < save) save--;
-      }
-    } else {
-      owl_editwin_key_right(e);
-    }
-  }
-
-  /* put cursor back at starting point */
+    owl_editwin_point_move(e, 1);
+  }
+
   oe_restore_excursion(e, &x);
-#endif
 }
 
