Index: editwin.c
===================================================================
--- editwin.c	(revision bd1a1ae26f1b49e0abbba68d6825650707a9911b)
+++ editwin.c	(revision e20d8179b1fbc0ba21fd86101cc72d18fcc65cf5)
@@ -32,4 +32,7 @@
 } _owl_editwin_excursion;
 
+static int owl_editwin_is_char_in(owl_editwin *e, char *set);
+static void oe_reframe(owl_editwin *e);
+
 #define INCR 5000
 
@@ -45,5 +48,5 @@
 void owl_editwin_init(owl_editwin *e, WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
 {
-  e->buff=owl_malloc(INCR);  
+  e->buff=owl_malloc(INCR);
   e->buff[0]='\0';
   e->bufflen=0;
@@ -262,5 +265,31 @@
   e->topindex = -1;
 }
-static void owl_editwin_reframe(owl_editwin *e) { /* noproto */
+
+static inline char *oe_next_point(owl_editwin *e, char *p)
+{
+  char *boundary = e->buff + e->bufflen + 1;
+  char *q;
+
+  q = g_utf8_find_next_char(p, boundary);
+  while (q && g_unichar_ismark(g_utf8_get_char(q)))
+    q = g_utf8_find_next_char(q, boundary);
+
+  if (q == p)
+    return NULL;
+  return q;
+}
+
+static inline char *oe_prev_point(owl_editwin *e, char *p)
+{
+  char *boundary = e->buff + e->lock;
+
+  p = g_utf8_find_prev_char(boundary, p);
+  while (p && g_unichar_ismark(g_utf8_get_char(p)))
+    p = g_utf8_find_prev_char(boundary, p);
+
+  return p;
+}
+
+static void oe_reframe(owl_editwin *e) {
   e->topindex = 0; /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
 }
@@ -278,6 +307,6 @@
   do {
     if (e->topindex == -1 || e->index < e->topindex)
-      owl_editwin_reframe(e);
-    
+      oe_reframe(e);
+
     line = 0;
     index = e->topindex;
@@ -299,5 +328,5 @@
 	  break;
 	width += cw;
-	p = g_utf8_find_next_char(e->buff + index, e->buff + e->bufflen);
+	p = oe_next_point(e, e->buff + index);
 	if (p == NULL) /* we ran off the end */
 	  break;
@@ -323,5 +352,5 @@
     }
   } while(x == -1);
-  
+
   if (x != -1)
     wmove(e->curswin, y, x);
@@ -338,5 +367,5 @@
     e->buff[i-n] = e->buff[i];
   }
-  
+
   e->bufflen -= n;
   e->buff[e->bufflen] = '\0';
@@ -462,5 +491,5 @@
     c = '\n';
   }
-  
+
   if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
     /* perhaps later this will change some state that allows the string
@@ -481,5 +510,5 @@
     }
   }
-  /* if not at the end of the buffer, adjust based in char size difference. */ 
+  /* if not at the end of the buffer, adjust based in char size difference. */
   else if (oldlen > newlen) {
     _owl_editwin_remove_bytes(e, oldlen-newlen);
@@ -492,5 +521,5 @@
     e->buff[e->index + i] = tmp[i];
   }
-       
+
   /* housekeeping */
   if (e->index == e->bufflen) {
@@ -498,5 +527,5 @@
     e->buff[e->bufflen] = '\0';
   }
-  
+
   /* advance the cursor */
   e->index += newlen;
@@ -505,5 +534,5 @@
 /* delete the character at the current point, following chars
  * shift left.
- */ 
+ */
 void owl_editwin_delete_char(owl_editwin *e)
 {
@@ -512,5 +541,5 @@
 
   if (e->bufflen == 0) return;
-  
+
   if (e->index == e->bufflen) return;
 
@@ -528,5 +557,5 @@
  * advance the pointer.  If point is at beginning of buffer do
  * nothing.  If point is after the last character swap point-1 with
- * point-2.  (Behaves as observed in tcsh and emacs).  
+ * point-2.  (Behaves as observed in tcsh and emacs).
  */
 void owl_editwin_transpose_chars(owl_editwin *e)
@@ -535,9 +564,9 @@
 
   if (e->bufflen == 0) return;
-  
+
   if (e->index == e->bufflen) {
     /* point is after last character */
     e->index--;
-  }  
+  }
 
   if (e->index - 1 < e->lock) {
@@ -549,15 +578,12 @@
   p1 = e->buff + e->index;
 
-  p2 = g_utf8_find_next_char(p1, NULL);
-  while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
-    p2 = g_utf8_find_next_char(p2, NULL);
-  }
-  if (p2 == NULL) return;
-
-  p3 = g_utf8_find_prev_char(e->buff, p1);
-  while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
-    p3 = g_utf8_find_prev_char(p3, NULL);
-  }
-  if (p3 == NULL) return;
+  p2 = oe_next_point(e, p1); /* XXX make sure we can't transpose past the end
+				of the buffer */
+  if (p2 == NULL)
+    return;
+
+  p3 = oe_prev_point(e, p1);
+  if (p3 == NULL)
+    return;
 
   tmp = owl_malloc(p2 - p3 + 5);
@@ -639,7 +665,7 @@
 }
 
-int owl_editwin_point_move(owl_editwin *e, int delta) /*noproto*/
-{
-  char *p, *boundary;
+int owl_editwin_point_move(owl_editwin *e, int delta)
+{
+  char *p;
   int change, index, d = 0;
 
@@ -647,24 +673,12 @@
   p = e->buff + e->index;
 
-  boundary = e->buff + (delta > 0 ? (e->bufflen + 1) : e->lock);
-
   while (d < change && p != NULL) {
-    if (delta > 0) {
-      p = g_utf8_find_next_char(p, boundary);
-      while (p && g_unichar_ismark(g_utf8_get_char(p)))
-	p = g_utf8_find_next_char(p, boundary);
-    } else {
-      p = g_utf8_find_prev_char(boundary, p);
-      while (p && g_unichar_ismark(g_utf8_get_char(p)))
-	p = g_utf8_find_prev_char(boundary, p);
-    }
-    if (p != NULL) { 
-      index = p - e->buff;
-      if (index != e->index) { /* XXX rethink the loop termination condition
-				  above */
-	e->index = index;
-	d++;
-      } else
-	break;
+    if (delta > 0)
+      p = oe_next_point(e, p);
+    else
+      p = oe_prev_point(e, p);
+    if (p != NULL) {
+      e->index = p - e->buff;
+      d++;
     }
   }
@@ -706,5 +720,5 @@
 }
 
-int _owl_editwin_is_char_in(owl_editwin *e, char *set) /*noproto*/
+static int owl_editwin_is_char_in(owl_editwin *e, char *set)
 {
   char *p;
@@ -716,8 +730,8 @@
 }
 
-int owl_editwin_move_if_in(owl_editwin *e, int delta, char *set) /*noproto*/
+int owl_editwin_move_if_in(owl_editwin *e, int delta, char *set)
 {
   int change, distance = 0;
-  while (_owl_editwin_is_char_in(e, set)) {
+  while (owl_editwin_is_char_in(e, set)) {
     change = owl_editwin_point_move(e, delta);
     distance += change;
@@ -728,8 +742,8 @@
 }
 
-int owl_editwin_move_if_not_in(owl_editwin *e, int delta, char *set) /*noproto*/
+int owl_editwin_move_if_not_in(owl_editwin *e, int delta, char *set)
 {
   int change, distance = 0;
-  while (!_owl_editwin_is_char_in(e, set)) {
+  while (!owl_editwin_is_char_in(e, set)) {
     change = owl_editwin_point_move(e, delta);
     distance += change;
@@ -740,5 +754,5 @@
 }
 
-int owl_editwin_move_to_beginning_of_line(owl_editwin *e) /* noproto */
+int owl_editwin_move_to_beginning_of_line(owl_editwin *e)
 {
   int distance = 0;
@@ -754,11 +768,11 @@
   return distance;
 }
-  
-int owl_editwin_move_to_end_of_line(owl_editwin *e) /* noproto */
+
+int owl_editwin_move_to_end_of_line(owl_editwin *e)
 {
   return owl_editwin_move_if_not_in(e, 1, "\n");
 }
 
-int owl_editwin_line_move(owl_editwin *e, int delta) /*noproto*/
+int owl_editwin_line_move(owl_editwin *e, int delta)
 {
   int goal_column, change, ll, count = 0, distance = 0;
@@ -849,5 +863,5 @@
   /* if at beginning of a word, find beginning of previous word */
 
-  if (_owl_editwin_is_char_in(e, WHITESPACE)) {
+  if (owl_editwin_is_char_in(e, WHITESPACE)) {
     /* if in whitespace past end of word, find a word , the find the beginning*/
     owl_editwin_move_if_in(e, -1, WHITESPACE); /* leaves us on the last
@@ -856,5 +870,5 @@
     /* are we at the beginning of a word? */
     owl_editwin_point_move(e, -1);
-    beginning = _owl_editwin_is_char_in(e, WHITESPACE);
+    beginning = owl_editwin_is_char_in(e, WHITESPACE);
     owl_editwin_restore_excursion(e, &x);
     if (beginning)
@@ -864,5 +878,5 @@
     owl_editwin_save_excursion(e, &x);
     owl_editwin_point_move(e, -1);
-    if (_owl_editwin_is_char_in(e, WHITESPACE)) { /* we were at the beginning */
+    if (owl_editwin_is_char_in(e, WHITESPACE)) { /* we were at the beginning */
       owl_editwin_move_to_previousword(e); /* previous case */
       return;
@@ -1049,5 +1063,5 @@
     return;
   }
-  owl_editwin_redisplay(e, 0);  
+  owl_editwin_redisplay(e, 0);
 }
 
@@ -1064,5 +1078,5 @@
   if (j.ch == ERR) return;
   /* Ignore ncurses control characters. */
-  if (j.ch < 0x100) { 
+  if (j.ch < 0x100) {
     _owl_editwin_process_char(e, j.uch);
   }
@@ -1080,5 +1094,5 @@
 
   if (e->bufflen==0) return(0);
-  
+
   /* first go to the yth line */
   ptr1=e->buff;
@@ -1111,2 +1125,12 @@
   return e->echochar;
 }
+
+void owl_editwin_set_goal_column(owl_editwin *e, int column)
+{
+  e->goal_column = column;
+}
+
+int owl_editwin_get_goal_column(owl_editwin *e)
+{
+  return e->goal_column;
+}
