Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1fd0b25bc362ef6deee5d05e4558ce154f8c6f5c)
+++ ChangeLog	(revision 59cf91cb0f6e1655c515361fd9432f10ada5c863)
@@ -8,5 +8,10 @@
 	renamed owl_fmtext_ztext_stylestrip to owl_function_ztext_styletsrip
 	     and put it in functions.c
-
+	Attempts to stay near the current message when switching views.
+	     When switching from an empty view to one we've previously
+	     been in, the new current message position will attempt
+	     to be close to the current position from the last 
+	     time we visited that view.
+	
 1.2.1
         New framework for command handling.
Index: filter.c
===================================================================
--- filter.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ filter.c	(revision 59cf91cb0f6e1655c515361fd9432f10ada5c863)
@@ -21,4 +21,5 @@
   f->polarity=0;
   f->color=OWL_COLOR_DEFAULT;
+  f->cachedmsgid=-1;
   owl_list_create(&(f->fes));
 
@@ -95,4 +96,12 @@
 int owl_filter_get_color(owl_filter *f) {
   return(f->color);
+}
+
+void owl_filter_set_cachedmsgid(owl_filter *f, int cachedmsgid) {
+  f->cachedmsgid=cachedmsgid;
+}
+
+int owl_filter_get_cachedmsgid(owl_filter *f) {
+  return(f->cachedmsgid);
 }
 
Index: functions.c
===================================================================
--- functions.c	(revision 37c27cfcea462c4957becbcc080af5ea88911d10)
+++ functions.c	(revision 59cf91cb0f6e1655c515361fd9432f10ada5c863)
@@ -1667,6 +1667,14 @@
   owl_view *v;
   owl_filter *f;
+  int curid=-1, newpos;
+  owl_message *curm;
 
   v=owl_global_get_current_view(&g);
+  curm=owl_view_get_element(v, owl_global_get_curmsg(&g));
+  if (curm) {
+    curid = owl_message_get_id(curm);
+    owl_view_save_curmsgid(v, curid);
+  }
+
   f=owl_global_get_filter(&g, filtname);
   if (!f) {
@@ -1678,5 +1686,17 @@
   owl_view_create(v, f);
 
-  owl_global_set_curmsg(&g, 0);
+  /* Figure out where to set the current message to.
+   * - If the previous view had messages in it, go to the closest message
+   *   to the last message in that view. 
+   * - If the previous view was empty, attempts to restore the position
+   *   from the last time we were in that view.  */
+  if (curm) {
+    newpos = owl_view_get_nearest_to_msgid(v, curid);
+  } else {
+    newpos = owl_view_get_nearest_to_saved(v);
+  }
+
+  owl_global_set_curmsg(&g, newpos);
+
   owl_global_set_curmsg_vert_offset(&g, 0);
   owl_global_set_direction_downwards(&g);
Index: owl.h
===================================================================
--- owl.h	(revision 1fd0b25bc362ef6deee5d05e4558ce154f8c6f5c)
+++ owl.h	(revision 59cf91cb0f6e1655c515361fd9432f10ada5c863)
@@ -289,4 +289,5 @@
   owl_list fes; /* filterelements */
   int color;
+  int cachedmsgid;  /* cached msgid: should move into view eventually */
 } owl_filter;
 
Index: view.c
===================================================================
--- view.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ view.c	(revision 59cf91cb0f6e1655c515361fd9432f10ada5c863)
@@ -56,4 +56,32 @@
 }
 
+/* Returns the position in the view with a message closest 
+ * to the passed msgid. */
+int owl_view_get_nearest_to_msgid(owl_view *v, int targetid) {
+  int i, bestdist=-1, bestpos=0, curid, curdist;
+
+  for (i=0; i<owl_view_get_size(v); i++) {
+    curid = owl_message_get_id(owl_view_get_element(v, i));
+    curdist = abs(targetid-curid);
+    if (bestdist<0 || curdist<bestdist) {
+      bestdist = curdist;
+      bestpos = i;
+    }
+  }
+  return bestpos;
+}
+
+int owl_view_get_nearest_to_saved(owl_view *v) {
+  int cachedid = owl_filter_get_cachedmsgid(v->filter);
+  if (cachedid<0) return(0);
+  return owl_view_get_nearest_to_msgid(v, cachedid);
+}
+
+/* saves the current message position in the filter so it can 
+ * be restored later if we switch back to this filter. */
+void owl_view_save_curmsgid(owl_view *v, int curid) {
+  owl_filter_set_cachedmsgid(v->filter, curid);
+}
+
 char *owl_view_get_filtname(owl_view *v) {
   return(owl_filter_get_name(v->filter));
